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 2019/10/09 14:17:45 UTC
[isis] 04/04: ISIS-2158: introduces a DeficiencyFacet
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch v2
in repository https://gitbox.apache.org/repos/asf/isis.git
commit 175dd48e1433e309eff73e375b972e758bff8a63
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Oct 9 16:17:31 2019 +0200
ISIS-2158: introduces a DeficiencyFacet
- facets of this particular type do now get added directly to the
meta-model during validation; these are specifically added to the
facet-holder, that is considered responsible for the failure
- this automatically allows for the meta-model export to also include
deficiency facets, explaining what's going wrong, right at the place
where they originate from
---
.../isis/metamodel/facetapi/FacetAbstract.java | 18 ++--
...nChoicesForCollectionParameterFacetFactory.java | 18 ++--
.../annotation/HomePageFacetAnnotationFactory.java | 41 ++++---
.../facets/all/deficiencies/DeficiencyFacet.java | 118 +++++++++++++++++++++
.../annotation/SortedByFacetAnnotationFactory.java | 7 +-
.../metamodel/facets/jaxb/JaxbFacetFactory.java | 53 +++++----
.../ViewModelSemanticCheckingFacetFactory.java | 35 ++++--
.../BookmarkPolicyFacetFallbackFactory.java | 4 +-
.../DomainObjectAnnotationFacetFactory.java | 29 +++--
.../DomainServiceFacetAnnotationFactory.java | 13 +--
.../mixin/MetaModelValidatorForMixinTypes.java | 10 +-
.../mixin/MixinFacetForMixinAnnotationFactory.java | 4 +-
.../NavigableParentAnnotationFacetFactory.java | 8 +-
...jectSpecIdFacetDerivedFromClassNameFactory.java | 13 ++-
.../recreatable/RecreatableObjectFacetFactory.java | 5 +-
.../annotation/TitleAnnotationFacetFactory.java | 5 +-
...engthFacetForMaxLengthAnnotationOnProperty.java | 35 ------
.../progmodel/ProgrammingModelService.java | 7 +-
.../specloader/ProgrammingModelServiceDefault.java | 17 ---
.../metamodel/specloader/SpecificationLoader.java | 13 ++-
.../specloader/SpecificationLoaderDefault.java | 23 +++-
.../specloader/validator/MetaModelValidator.java | 28 +++--
.../validator/MetaModelValidatorAbstract.java | 26 +++++
.../validator/MetaModelValidatorComposite.java | 65 ------------
...etaModelValidatorForConflictingOptionality.java | 23 ++--
.../MetaModelValidatorForDeprecatedAbstract.java | 17 +--
...etaModelValidatorForDeprecatedMethodPrefix.java | 4 +-
.../MetaModelValidatorForValidationFailures.java | 13 +--
.../validator/MetaModelValidatorVisiting.java | 35 +++---
.../ViewModelSemanticCheckingFacetFactoryTest.java | 6 +-
.../jdo/metamodel/JdoProgrammingModelPlugin.java | 64 ++++++-----
.../object/query/VisitorForClauseAbstract.java | 22 ++--
.../facets/object/query/VisitorForFromClause.java | 7 +-
.../object/query/VisitorForVariablesClause.java | 7 +-
.../version/JdoVersionAnnotationFacetFactory.java | 11 +-
...DerivedFromJdoColumnAnnotationFacetFactory.java | 18 ++--
...ndatoryFromJdoColumnAnnotationFacetFactory.java | 27 +++--
...DerivedFromJdoColumnAnnotationFacetFactory.java | 29 ++---
...AnnotationFacetFactoryTest_refineMetaModel.java | 35 +++---
.../system/session/IsisSessionFactoryDefault.java | 7 +-
.../validate/ValidateDomainModel.java | 6 +-
.../domainmodel/SpecloaderPerformanceTest.java | 4 +-
.../SupportingMethodValidatorRefinerFactory.java | 3 +-
43 files changed, 525 insertions(+), 408 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facetapi/FacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facetapi/FacetAbstract.java
index 87a04f3..0689275 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facetapi/FacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facetapi/FacetAbstract.java
@@ -20,14 +20,13 @@
package org.apache.isis.metamodel.facetapi;
import java.util.Map;
-import java.util.Objects;
-import java.util.stream.Stream;
-import org.apache.isis.commons.internal.assertions._Ensure;
import org.apache.isis.metamodel.MetaModelContext;
import static org.apache.isis.commons.internal.base._With.requires;
+import lombok.val;
+
public abstract class FacetAbstract implements Facet, MetaModelContext.Delegating {
@@ -99,10 +98,10 @@ public abstract class FacetAbstract implements Facet, MetaModelContext.Delegatin
throw new IllegalArgumentException("illegal argument, expected underlying facet (a multi-valued facet) to have equivalent to the facet type (or facet types) of this facet");
}
} else {
- _Ensure.ensureThatArg(
- underlyingFacet.facetType(),
- type->Objects.equals(type, facetType),
- ()->String.format("type-missmatch: underlying facet's type '%s' must match this facet's type '%s'"));
+// _Ensure.ensureThatArg(
+// underlyingFacet.facetType(),
+// type->Objects.equals(type, facetType),
+// ()->String.format("type-missmatch: underlying facet's type '%s' must match this facet's type '%s'"));
}
}
this.underlyingFacet = underlyingFacet;
@@ -114,9 +113,8 @@ public abstract class FacetAbstract implements Facet, MetaModelContext.Delegatin
return multiTypedFacet.containsFacetTypeOf(this.facetType);
}
- final MultiTypedFacet thisAsMultiTyped = (MultiTypedFacet) this;
- final Stream<Class<? extends Facet>> facetTypes = thisAsMultiTyped.facetTypes();
- return facetTypes
+ val thisAsMultiTyped = (MultiTypedFacet) this;
+ return thisAsMultiTyped.facetTypes()
.anyMatch(facetType->multiTypedFacet.containsFacetTypeOf(facetType));
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/ActionChoicesForCollectionParameterFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/ActionChoicesForCollectionParameterFacetFactory.java
index 118dd85..8f18efc 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/ActionChoicesForCollectionParameterFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/ActionChoicesForCollectionParameterFacetFactory.java
@@ -33,8 +33,8 @@ import org.apache.isis.metamodel.spec.feature.ObjectAction;
import org.apache.isis.metamodel.spec.feature.ObjectActionParameter;
import org.apache.isis.metamodel.specloader.specimpl.ObjectActionContributee;
import org.apache.isis.metamodel.specloader.specimpl.ObjectActionMixedIn;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
import lombok.val;
@@ -69,14 +69,14 @@ implements MetaModelRefiner {
@Override
public boolean visit(
final ObjectSpecification objectSpec,
- final ValidationFailures validationFailures) {
- validate(objectSpec, validationFailures);
+ final MetaModelValidator validator) {
+ validate(objectSpec, validator);
return true;
}
private void validate(
final ObjectSpecification objectSpec,
- final ValidationFailures validationFailures) {
+ final MetaModelValidator validator) {
objectSpec.streamObjectActions(Contributed.INCLUDED)
.forEach(objectAction->{
if(objectAction instanceof ObjectActionMixedIn || objectAction instanceof ObjectActionContributee) {
@@ -87,7 +87,7 @@ implements MetaModelRefiner {
int paramNum = 0;
for (ObjectActionParameter parameter : objectAction.getParameters()) {
if(parameter.getFeatureType() == FeatureType.ACTION_PARAMETER_COLLECTION) {
- validate(objectSpec, objectAction, parameter, paramNum, validationFailures);
+ validate(objectSpec, objectAction, parameter, paramNum, validator);
}
paramNum++;
}
@@ -99,7 +99,7 @@ implements MetaModelRefiner {
final ObjectAction objectAction,
final ObjectActionParameter parameter,
final int paramNum,
- final ValidationFailures validationFailures) {
+ final MetaModelValidator validator) {
final CollectionSemanticsFacet collectionSemantics =
@@ -109,7 +109,8 @@ implements MetaModelRefiner {
// from java.util.Collection but are not of
// exact type List, Set, SortedSet or Collection.
if(!collectionSemantics.value().isSupportedInterfaceForActionParameters()) {
- validationFailures.add(
+ validator.onFailure(
+ objectSpec,
objectSpec.getIdentifier(),
"Collection action parameter found that is not exactly one "
+ "of the following supported types: "
@@ -135,7 +136,8 @@ implements MetaModelRefiner {
return;
}
- validationFailures.add(
+ validator.onFailure(
+ objectSpec,
objectSpec.getIdentifier(),
"Collection action parameter found without supporting "
+ "choices or autoComplete facet. "
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/homepage/annotation/HomePageFacetAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/homepage/annotation/HomePageFacetAnnotationFactory.java
index 3545863..05b3b92 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/homepage/annotation/HomePageFacetAnnotationFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/homepage/annotation/HomePageFacetAnnotationFactory.java
@@ -23,7 +23,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
import org.apache.isis.applib.Identifier;
import org.apache.isis.applib.annotation.HomePage;
@@ -39,9 +38,9 @@ import org.apache.isis.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.metamodel.spec.ObjectSpecification;
import org.apache.isis.metamodel.spec.feature.Contributed;
import org.apache.isis.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting.Visitor;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
import static org.apache.isis.commons.internal.functions._Predicates.not;
@@ -72,45 +71,53 @@ implements MetaModelRefiner {
private Visitor newValidatorVisitor() {
return new MetaModelValidatorVisiting.SummarizingVisitor() {
- private final List<Identifier> annotated = _Lists.newArrayList();
+ private final List<ObjectAction> actionsHavingHomePageFacet = _Lists.newArrayList();
@Override
- public boolean visit(ObjectSpecification objectSpec, ValidationFailures validationFailures) {
- final Stream<ObjectAction> objectActions = objectSpec.streamObjectActions(Contributed.EXCLUDED);
+ public boolean visit(ObjectSpecification objectSpec, MetaModelValidator validator) {
+
+ val objectActions =
+ objectSpec.streamObjectActions(Contributed.EXCLUDED);
objectActions
.filter(objectAction->objectAction.containsFacet(HomePageFacet.class))
.forEach(objectAction->{
+
+ actionsHavingHomePageFacet.add(objectAction);
- val identifier = objectAction.getIdentifier();
-
- // TODO: it would good to flag if the facet is found on any non-services, however
- // ObjectSpecification.isService(...) can only be trusted once a PersistenceSession exists.
+ // TODO: it would be good to flag if the facet is found on any non-services, however
+ // ObjectSpecification.isService(...) can only be trusted once a PersistenceSession
+ // exists.
// this ought to be improved upon at some point...
- annotated.add(identifier);
+
+ // TODO might collide with type level annotations as well
+
});
return true; // keep searching
}
@Override
- public void summarize(ValidationFailures validationFailures) {
- if(annotated.size()>1) {
+ public void summarize(MetaModelValidator validator) {
+ if(actionsHavingHomePageFacet.size()>1) {
- final Set<String> annotatedIdSet = annotated.stream()
+ final Set<String> homepageActionIdSet = actionsHavingHomePageFacet.stream()
+ .map(ObjectAction::getIdentifier)
.map(Identifier::toClassAndNameIdentityString)
.collect(Collectors.toCollection(HashSet::new));
- for (val actionIdentifier : annotated) {
+ for (val objectAction : actionsHavingHomePageFacet) {
+ val actionIdentifier = objectAction.getIdentifier();
val actionId = actionIdentifier.toClassAndNameIdentityString();
- val nonServiceNamesStr = annotatedIdSet.stream()
+ val colission = homepageActionIdSet.stream()
.filter(not(actionId::equals))
.collect(Collectors.joining(", "));
- validationFailures.add(
+ validator.onFailure(
+ objectAction,
actionIdentifier,
"%s: other actions also specified as home page: %s ",
- actionId, nonServiceNamesStr);
+ actionId, colission);
}
}
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/all/deficiencies/DeficiencyFacet.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/all/deficiencies/DeficiencyFacet.java
new file mode 100644
index 0000000..5cd3d07
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/all/deficiencies/DeficiencyFacet.java
@@ -0,0 +1,118 @@
+/*
+ * 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.metamodel.facets.all.deficiencies;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.isis.applib.Identifier;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.metamodel.facetapi.Facet;
+import org.apache.isis.metamodel.facetapi.FacetHolder;
+
+import static org.apache.isis.commons.internal.base._With.computeIfAbsent;
+
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.Value;
+import lombok.val;
+
+/**
+ * Collects meta-model validation failures (deficiencies) directly on the holder that is involved.
+ * @since 2.0
+ */
+@RequiredArgsConstructor(staticName = "of")
+public final class DeficiencyFacet implements Facet {
+
+ @NonNull @Getter private final FacetHolder facetHolder;
+ @NonNull @Getter private final List<Deficiency> deficiencies;
+
+ @Value(staticConstructor = "of")
+ public static final class Deficiency {
+ @NonNull @Getter private Identifier deficiencyOrigin;
+ @NonNull @Getter private String deficiencyMessage;
+ }
+
+ /**
+ * Create a new DeficiencyFacet for the facetHolder (if it not already has one),
+ * then adds given deficiency information to the facet.
+ * @param facetHolder
+ * @param deficiencyOrigin
+ * @param deficiencyMessage
+ * @return
+ */
+ public static DeficiencyFacet appendTo(
+ @NonNull FacetHolder facetHolder,
+ @NonNull Identifier deficiencyOrigin,
+ @NonNull String deficiencyMessage) {
+
+ val deficiencyFacet = computeIfAbsent(facetHolder.getFacet(DeficiencyFacet.class),
+ ()->DeficiencyFacet.of(facetHolder, new ArrayList<>()));
+
+ deficiencyFacet.getDeficiencies().add(Deficiency.of(deficiencyOrigin, deficiencyMessage));
+ return deficiencyFacet;
+ }
+
+ // -- FACET IMPLEMENTATION
+
+ @Override
+ public void setFacetHolder(FacetHolder facetHolder) {
+ throw _Exceptions.unsupportedOperation();
+ }
+
+ @Override
+ public Facet getUnderlyingFacet() {
+ return null;
+ }
+
+ @Override
+ public void setUnderlyingFacet(Facet underlyingFacet) {
+ throw _Exceptions.unsupportedOperation();
+ }
+
+ @Override
+ public Class<? extends Facet> facetType() {
+ return DeficiencyFacet.class;
+ }
+
+ @Override
+ public boolean isDerived() {
+ return false;
+ }
+
+ @Override
+ public boolean isNoop() {
+ return true;
+ }
+
+ @Override
+ public boolean alwaysReplace() {
+ return false;
+ }
+
+ @Override
+ public void appendAttributesTo(Map<String, Object> attributeMap) {
+ throw _Exceptions.unsupportedOperation();
+ }
+
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/collections/sortedby/annotation/SortedByFacetAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/collections/sortedby/annotation/SortedByFacetAnnotationFactory.java
index 4d279d3..b2733b9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/collections/sortedby/annotation/SortedByFacetAnnotationFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/collections/sortedby/annotation/SortedByFacetAnnotationFactory.java
@@ -31,9 +31,9 @@ import org.apache.isis.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.metamodel.spec.ObjectSpecification;
import org.apache.isis.metamodel.spec.feature.Contributed;
import org.apache.isis.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting.Visitor;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
/**
* There is no check that the value is a {@link Comparator}; instead this is done through
@@ -63,7 +63,7 @@ implements MetaModelRefiner {
return new MetaModelValidatorVisiting.Visitor() {
@Override
- public boolean visit(ObjectSpecification objectSpec, ValidationFailures validationFailures) {
+ public boolean visit(ObjectSpecification objectSpec, MetaModelValidator validator) {
final Stream<OneToManyAssociation> objectCollections = objectSpec.streamCollections(Contributed.EXCLUDED);
objectCollections.forEach(objectCollection->{
@@ -71,7 +71,8 @@ implements MetaModelRefiner {
if(facet != null) {
final Class<? extends Comparator<?>> cls = facet.value();
if(!Comparator.class.isAssignableFrom(cls)) {
- validationFailures.add(
+ validator.onFailure(
+ objectSpec,
objectSpec.getIdentifier(),
"%s#%s: is annotated with @SortedBy, but the class specified '%s' is not a Comparator",
objectSpec.getIdentifier().getClassName(),
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/jaxb/JaxbFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/jaxb/JaxbFacetFactory.java
index dd1ff6c..f2100a5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/jaxb/JaxbFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/jaxb/JaxbFacetFactory.java
@@ -46,8 +46,8 @@ import org.apache.isis.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.metamodel.spec.ObjectSpecification;
import org.apache.isis.metamodel.spec.feature.Contributed;
import org.apache.isis.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
/**
* just adds a validator
@@ -157,15 +157,15 @@ implements MetaModelRefiner {
@Override
public boolean visit(
final ObjectSpecification objectSpec,
- final ValidationFailures validationFailures) {
+ final MetaModelValidator validator) {
- validate(objectSpec, validationFailures);
+ validate(objectSpec, validator);
return true;
}
private void validate(
final ObjectSpecification objectSpec,
- final ValidationFailures validationFailures) {
+ final MetaModelValidator validator) {
final boolean viewModel = objectSpec.isViewModel();
if(!viewModel) {
@@ -178,7 +178,7 @@ implements MetaModelRefiner {
}
for (final TypeValidator typeValidator : typeValidators) {
- typeValidator.validate(objectSpec, validationFailures);
+ typeValidator.validate(objectSpec, validator);
}
final Stream<OneToOneAssociation> properties = objectSpec
@@ -189,7 +189,7 @@ implements MetaModelRefiner {
.filter(property->property.containsDoOpFacet(PropertySetterFacet.class))
.forEach(property->{
for (final PropertyValidator adapterValidator : propertyValidators) {
- adapterValidator.validate(objectSpec, property, validationFailures);
+ adapterValidator.validate(objectSpec, property, validator);
}
});
@@ -231,7 +231,7 @@ implements MetaModelRefiner {
private static abstract class TypeValidator {
abstract void validate(
final ObjectSpecification objectSpec,
- final ValidationFailures validationFailures);
+ final MetaModelValidator validator);
}
@@ -239,7 +239,7 @@ implements MetaModelRefiner {
abstract void validate(
final ObjectSpecification objectSpec,
final OneToOneAssociation property,
- final ValidationFailures validationFailures);
+ final MetaModelValidator validator);
}
@@ -249,7 +249,7 @@ implements MetaModelRefiner {
void validate(
final ObjectSpecification objectSpec,
final OneToOneAssociation property,
- final ValidationFailures validationFailures) {
+ final MetaModelValidator validator) {
final ObjectSpecification propertyTypeSpec = property.getSpecification();
if (!propertyTypeSpec.isEntity()) {
@@ -262,7 +262,8 @@ implements MetaModelRefiner {
return;
}
final Class<?> propertyType = propertyTypeSpec.getCorrespondingClass();
- validationFailures.add(
+ validator.onFailure(
+ property,
property.getIdentifier(),
"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.schema.utils.jaxbadapters.PersistentEntityAdapter.class) or equivalent.",
objectSpec.getFullIdentifier(),
@@ -283,7 +284,7 @@ implements MetaModelRefiner {
void validate(
final ObjectSpecification objectSpec,
final OneToOneAssociation property,
- final ValidationFailures validationFailures) {
+ final MetaModelValidator validator) {
final ObjectSpecification propertyTypeSpec = property.getSpecification();
final Class<?> propertyType = propertyTypeSpec.getCorrespondingClass();
@@ -304,7 +305,8 @@ implements MetaModelRefiner {
}
// else
- validationFailures.add(
+ validator.onFailure(
+ property,
property.getIdentifier(),
"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(),
@@ -317,10 +319,11 @@ implements MetaModelRefiner {
@Override
void validate(
final ObjectSpecification objectSpec,
- final ValidationFailures validationFailures) {
+ final MetaModelValidator validator) {
if(objectSpec.isAbstract()) {
- validationFailures.add(
+ validator.onFailure(
+ objectSpec,
objectSpec.getIdentifier(),
"JAXB view model '%s' is abstract",
objectSpec.getFullIdentifier());
@@ -332,21 +335,24 @@ implements MetaModelRefiner {
@Override
void validate(
final ObjectSpecification objectSpec,
- final ValidationFailures validationFailures) {
+ final MetaModelValidator validator) {
final Class<?> correspondingClass = objectSpec.getCorrespondingClass();
if(correspondingClass.isAnonymousClass()) {
- validationFailures.add(
+ validator.onFailure(
+ objectSpec,
objectSpec.getIdentifier(),
"JAXB view model '%s' is an anonymous class",
objectSpec.getFullIdentifier());
} else if(correspondingClass.isLocalClass()) {
- validationFailures.add(
+ validator.onFailure(
+ objectSpec,
objectSpec.getIdentifier(),
"JAXB view model '%s' is a local class",
objectSpec.getFullIdentifier());
} else if(correspondingClass.isMemberClass() && !Modifier.isStatic(correspondingClass.getModifiers())) {
- validationFailures.add(
+ validator.onFailure(
+ objectSpec,
objectSpec.getIdentifier(),
"JAXB view model '%s' is an non-static inner class",
objectSpec.getFullIdentifier());
@@ -358,22 +364,25 @@ implements MetaModelRefiner {
@Override
void validate(
final ObjectSpecification objectSpec,
- final ValidationFailures validationFailures) {
+ final MetaModelValidator validator) {
final Class<?> correspondingClass = objectSpec.getCorrespondingClass();
final Constructor<?>[] constructors = correspondingClass.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
if(constructor.getParameterCount() == 0) {
if (!Modifier.isPublic(constructor.getModifiers())) {
- validationFailures
- .add(objectSpec.getIdentifier(),
+ validator
+ .onFailure(
+ objectSpec,
+ objectSpec.getIdentifier(),
"JAXB view model '%s' has a no-arg constructor, however it is not public",
objectSpec.getFullIdentifier());
}
return;
}
}
- validationFailures.add(
+ validator.onFailure(
+ objectSpec,
objectSpec.getIdentifier(),
"JAXB view model '%s' does not have a public no-arg constructor",
objectSpec.getFullIdentifier());
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/ViewModelSemanticCheckingFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/ViewModelSemanticCheckingFacetFactory.java
index ea9b7d9..17a2f18 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/ViewModelSemanticCheckingFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/ViewModelSemanticCheckingFacetFactory.java
@@ -33,6 +33,8 @@ import org.apache.isis.metamodel.facets.FacetFactoryAbstract;
import org.apache.isis.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorForValidationFailures;
+import lombok.val;
+
public class ViewModelSemanticCheckingFacetFactory extends FacetFactoryAbstract
implements MetaModelRefiner {
@@ -54,7 +56,8 @@ implements MetaModelRefiner {
return;
}
- final Class<?> cls = processClassContext.getCls();
+ val cls = processClassContext.getCls();
+ val facetHolder = processClassContext.getFacetHolder();
final DomainObjectLayout domainObjectLayout = Annotations.getAnnotation(cls, DomainObjectLayout.class);
final ViewModelLayout viewModelLayout = Annotations.getAnnotation(cls, ViewModelLayout.class);
@@ -70,7 +73,8 @@ implements MetaModelRefiner {
final boolean annotatedWithViewModel = viewModel != null;
if(implementsViewModel && implementsRecreatableDomainObject) {
- validator.addFailure(
+ validator.onFailure(
+ facetHolder,
Identifier.classIdentifier(cls),
"Inconsistent view model / domain object semantics; %s should not implement both %s and %s interfaces (implement one or the other)",
cls.getName(),
@@ -79,7 +83,8 @@ implements MetaModelRefiner {
}
if(implementsViewModel && annotatedWithDomainObject) {
- validator.addFailure(
+ validator.onFailure(
+ facetHolder,
Identifier.classIdentifier(cls),
"Inconsistent view model / domain object semantics; %1$s should not implement %2$s and be annotated with @%3$s (annotate with %4$s instead of %2$s, or implement %5s instead of %2$s)",
cls.getName(),
@@ -90,7 +95,8 @@ implements MetaModelRefiner {
);
}
if(implementsViewModel && annotatedWithDomainObjectLayout) {
- validator.addFailure(
+ validator.onFailure(
+ facetHolder,
Identifier.classIdentifier(cls),
"Inconsistent view model / domain object semantics; %1$s should not implement %2$s and be annotated with @%3$s (annotate with @%4$s instead of %3$s, or implement %5$s instead of %2$s)",
cls.getName(),
@@ -102,7 +108,8 @@ implements MetaModelRefiner {
if(annotatedWithViewModel && implementsRecreatableDomainObject) {
- validator.addFailure(
+ validator.onFailure(
+ facetHolder,
Identifier.classIdentifier(cls),
"Inconsistent view model / domain object semantics; %1$s should not be annotated with @%2$s but implement @%3$s (implement %4$s instead of %3$s, or annotate with @%5$s with nature of %6s, %7s or %8s instead of annotating with @%2$s)",
cls.getName(),
@@ -116,7 +123,8 @@ implements MetaModelRefiner {
);
}
if(annotatedWithViewModel && annotatedWithDomainObject) {
- validator.addFailure(
+ validator.onFailure(
+ facetHolder,
Identifier.classIdentifier(cls),
"Inconsistent view model / domain object semantics; %1$s should not be annotated with both @%2$s and @%3$s (annotate with one or the other)",
cls.getName(),
@@ -125,7 +133,8 @@ implements MetaModelRefiner {
}
if(annotatedWithViewModel && annotatedWithDomainObjectLayout) {
- validator.addFailure(
+ validator.onFailure(
+ facetHolder,
Identifier.classIdentifier(cls),
"Inconsistent view model / domain object semantics; %1$s should not be annotated with both @%2$s and @%3$s (annotate with @%4$s instead of @%3$s, or annotate with @%5$s instead of @%2$s)",
cls.getName(),
@@ -136,7 +145,8 @@ implements MetaModelRefiner {
}
if(annotatedWithViewModelLayout && implementsRecreatableDomainObject) {
- validator.addFailure(
+ validator.onFailure(
+ facetHolder,
Identifier.classIdentifier(cls),
"Inconsistent view model / domain object semantics; %1$s should not be annotated with @%2$s but implement @%3$s (implement %4$s instead of %3$s, or annotate with %5$s instead of %2$s)",
cls.getName(),
@@ -146,7 +156,8 @@ implements MetaModelRefiner {
DomainObjectLayout.class.getSimpleName());
}
if(annotatedWithViewModelLayout && annotatedWithDomainObject) {
- validator.addFailure(
+ validator.onFailure(
+ facetHolder,
Identifier.classIdentifier(cls),
"Inconsistent view model / domain object semantics; %1$s should not be annotated with @%2$s and also be annotated with @%3$s (annotate with @%4$s instead of @%3$s, or instead annotate with @%5$s instead of @%2$s)",
cls.getName(),
@@ -156,7 +167,8 @@ implements MetaModelRefiner {
DomainObjectLayout.class.getSimpleName());
}
if(annotatedWithViewModelLayout && annotatedWithDomainObjectLayout) {
- validator.addFailure(
+ validator.onFailure(
+ facetHolder,
Identifier.classIdentifier(cls),
"Inconsistent view model / domain object semantics; %1$s should not be annotated with both @%2$s and @%3$s (annotate with one or the other)",
cls.getName(),
@@ -168,7 +180,8 @@ implements MetaModelRefiner {
if( annotatedWithDomainObject &&
(domainObject.nature() == Nature.NOT_SPECIFIED || domainObject.nature() == Nature.JDO_ENTITY) &&
implementsRecreatableDomainObject) {
- validator.addFailure(
+ validator.onFailure(
+ facetHolder,
Identifier.classIdentifier(cls),
"Inconsistent view model / domain object semantics; %1$s should not be annotated with @%2$s with nature of %3$s and also implement %4$s (specify a nature of %5$s, %6$s or %7$s)",
cls.getName(),
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/bookmarkpolicy/bookmarkable/BookmarkPolicyFacetFallbackFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/bookmarkpolicy/bookmarkable/BookmarkPolicyFacetFallbackFactory.java
index 10e6693..1bcbe48 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/bookmarkpolicy/bookmarkable/BookmarkPolicyFacetFallbackFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/bookmarkpolicy/bookmarkable/BookmarkPolicyFacetFallbackFactory.java
@@ -56,7 +56,7 @@ implements MetaModelRefiner {
@Override
public void refineProgrammingModel(ProgrammingModel programmingModel) {
- programmingModel.addValidator((objectSpec, validationFailures) -> {
+ programmingModel.addValidator((objectSpec, validator) -> {
final Stream<ObjectAction> objectActions = objectSpec.streamObjectActions(Contributed.EXCLUDED);
@@ -72,7 +72,7 @@ implements MetaModelRefiner {
.forEach(objectAction->{
final ActionSemanticsFacet semanticsFacet = objectAction.getFacet(ActionSemanticsFacet.class);
if(semanticsFacet == null || semanticsFacet.isNoop() || !semanticsFacet.value().isSafeInNature()) {
- validationFailures.add(
+ validator.onFailure(objectAction,
objectAction.getIdentifier(),
"%s: action is bookmarkable but action semantics are not explicitly indicated as being safe. " +
"Either add @Action(semantics=SemanticsOf.SAFE) or @Action(semantics=SemanticsOf.SAFE_AND_REQUEST_CACHEABLE), or remove @ActionLayout(bookmarking=...).",
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
index 3fc4b7b..5d9c333 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
@@ -73,9 +73,9 @@ import org.apache.isis.metamodel.facets.object.viewmodel.ViewModelFacet;
import org.apache.isis.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.metamodel.spec.ObjectSpecId;
import org.apache.isis.metamodel.spec.ObjectSpecification;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorForValidationFailures;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
import org.apache.isis.metamodel.util.EventUtil;
import lombok.val;
@@ -199,7 +199,13 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
.map(domainObject -> new AnnotHelper(domainObject))
.filter(a -> a.autoCompleteRepository != Object.class)
.filter(a -> {
- a.repositoryMethod = findRepositoryMethod(cls, "@DomainObject", a.autoCompleteRepository, a.autoCompleteAction);
+ a.repositoryMethod = findRepositoryMethod(
+ facetHolder,
+ cls,
+ "@DomainObject",
+ a.autoCompleteRepository,
+ a.autoCompleteAction);
+
return a.repositoryMethod != null;
})
.map(a -> new AutoCompleteFacetForDomainObjectAnnotation(
@@ -208,10 +214,12 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
}
private Method findRepositoryMethod(
+ final FacetHolder facetHolder,
final Class<?> cls,
final String annotationName,
final Class<?> repositoryClass,
final String methodName) {
+
final Method[] methods = repositoryClass.getMethods();
for (Method method : methods) {
if(method.getName().equals(methodName)) {
@@ -221,7 +229,8 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
}
}
}
- autoCompleteMethodInvalid.addFailure(
+ autoCompleteMethodInvalid.onFailure(
+ facetHolder,
Identifier.classIdentifier(cls),
"%s annotation on %s specifies method '%s' that does not exist in repository '%s'",
annotationName, cls.getName(), methodName, repositoryClass.getName());
@@ -298,7 +307,7 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
val mixinDomainObjectIfAny =
domainObjectIfAny
.filter(domainObject -> domainObject.nature() == Nature.MIXIN)
- .filter(domainObject -> mixinTypeValidator.ensureMixinType(cls));
+ .filter(domainObject -> mixinTypeValidator.ensureMixinType(facetHolder, cls));
val mixinFacet =
MixinFacetForDomainObjectAnnotation.create(mixinDomainObjectIfAny, cls, facetHolder, getServiceInjector());
@@ -486,13 +495,13 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
programmingModel.addValidator(new MetaModelValidatorVisiting.Visitor() {
@Override
- public boolean visit(final ObjectSpecification thisSpec, final ValidationFailures validationFailures) {
+ public boolean visit(final ObjectSpecification thisSpec, final MetaModelValidator validator) {
- validate(thisSpec, validationFailures);
+ validate(thisSpec, validator);
return true;
}
- private void validate(final ObjectSpecification thisSpec, final ValidationFailures validationFailures) {
+ private void validate(final ObjectSpecification thisSpec, final MetaModelValidator validator) {
if(!thisSpec.isEntityOrViewModel()) {
return;
}
@@ -516,7 +525,8 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
if (existingSpec == null) {
continue;
}
- validationFailures.add(
+ validator.onFailure(
+ existingSpec,
existingSpec.getIdentifier(),
"%s: cannot have two entities with same object type (@Discriminator, @DomainObject(objectType=...), @ObjectType or @PersistenceCapable(schema=...)); %s " +
"has same value (%s).",
@@ -531,7 +541,8 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
final Class<?> repositoryClass = facet.getRepositoryClass();
final boolean isResolvableBean = getServiceRegistry().isResolvableBean(repositoryClass);
if(!isResolvableBean) {
- validationFailures.add(
+ validator.onFailure(
+ thisSpec,
thisSpec.getIdentifier(),
"@DomainObject annotation on %s specifies unknown repository '%s'",
thisSpec.getFullIdentifier(), repositoryClass.getName());
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/domainservice/annotation/DomainServiceFacetAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/domainservice/annotation/DomainServiceFacetAnnotationFactory.java
index 3e6e65d..948bee5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/domainservice/annotation/DomainServiceFacetAnnotationFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/domainservice/annotation/DomainServiceFacetAnnotationFactory.java
@@ -34,9 +34,9 @@ import org.apache.isis.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.metamodel.spec.ObjectSpecification;
import org.apache.isis.metamodel.spec.feature.Contributed;
import org.apache.isis.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorForValidationFailures;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
import lombok.val;
@@ -84,7 +84,7 @@ implements MetaModelRefiner {
natureOfService,
"'isis.reflector.validator.mixinsOnly'");
- mixinOnlyValidator.addFailure(Identifier.classIdentifier(cls), msg);
+ mixinOnlyValidator.onFailure(facetHolder, Identifier.classIdentifier(cls), msg);
break;
default:
// no op
@@ -100,14 +100,14 @@ implements MetaModelRefiner {
programmingModel.addValidator(new MetaModelValidatorVisiting.Visitor() {
@Override
- public boolean visit(final ObjectSpecification thisSpec, final ValidationFailures validationFailures) {
- validate(thisSpec, validationFailures);
+ public boolean visit(final ObjectSpecification thisSpec, final MetaModelValidator validator) {
+ validate(thisSpec, validator);
return true;
}
private void validate(
final ObjectSpecification thisSpec,
- final ValidationFailures validationFailures) {
+ final MetaModelValidator validator) {
if(!thisSpec.containsFacet(DomainServiceFacet.class)) {
return;
@@ -125,7 +125,8 @@ implements MetaModelRefiner {
return;
}
- validationFailures.add(
+ validator.onFailure(
+ thisSpec,
thisSpec.getIdentifier(),
"%s: services can only have actions ('%s' config property), not properties or collections; annotate with @Programmatic if required. Found: %s",
thisSpec.getFullIdentifier(),
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java
index 1f3deac..9d37775 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java
@@ -20,8 +20,11 @@ package org.apache.isis.metamodel.facets.object.mixin;
import org.apache.isis.applib.Identifier;
import org.apache.isis.commons.internal.reflection._Reflect;
+import org.apache.isis.metamodel.facetapi.FacetHolder;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorForValidationFailures;
+import lombok.NonNull;
+
public class MetaModelValidatorForMixinTypes extends MetaModelValidatorForValidationFailures {
private final String annotation;
@@ -30,13 +33,16 @@ public class MetaModelValidatorForMixinTypes extends MetaModelValidatorForValida
this.annotation = annotation;
}
- public boolean ensureMixinType(final Class<?> candidateMixinType) {
+ public boolean ensureMixinType(
+ @NonNull FacetHolder facetHolder,
+ final Class<?> candidateMixinType) {
if (_Reflect.hasPublic1ArgConstructor(candidateMixinType)) {
return true;
}
- addFailure(
+ onFailure(
+ facetHolder,
Identifier.classIdentifier(candidateMixinType),
"%s: annotated with %s annotation but does not have a public 1-arg constructor",
candidateMixinType.getName(),
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/mixin/MixinFacetForMixinAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/mixin/MixinFacetForMixinAnnotationFactory.java
index b3c9d14..aa2c283 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/mixin/MixinFacetForMixinAnnotationFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/mixin/MixinFacetForMixinAnnotationFactory.java
@@ -45,11 +45,11 @@ extends FacetFactoryAbstract implements MetaModelRefiner {
return;
}
+ val facetHolder = processClassContext.getFacetHolder();
val candidateMixinType = processClassContext.getCls();
- if (!mixinTypeValidator.ensureMixinType(candidateMixinType)) {
+ if (!mixinTypeValidator.ensureMixinType(facetHolder, candidateMixinType)) {
return;
}
- val facetHolder = processClassContext.getFacetHolder();
val mixinFacet = MixinFacetForMixinAnnotation
.create(mixinIfAny.get(), candidateMixinType, facetHolder, getServiceInjector());
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/navparent/annotation/NavigableParentAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/navparent/annotation/NavigableParentAnnotationFacetFactory.java
index 85ebdf7..f5d6adc 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/navparent/annotation/NavigableParentAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/navparent/annotation/NavigableParentAnnotationFacetFactory.java
@@ -106,7 +106,7 @@ implements MetaModelRefiner {
@Override
public void refineProgrammingModel(ProgrammingModel programmingModel) {
- programmingModel.addValidator((objectSpec, validationFailures) -> {
+ programmingModel.addValidator((objectSpec, validate) -> {
final Class<?> cls = objectSpec.getCorrespondingClass();
@@ -119,7 +119,8 @@ implements MetaModelRefiner {
return true; // no conflict, continue validation processing
} else if (evaluators.size()>1) {
- validationFailures.add(
+ validate.onFailure(
+ objectSpec,
objectSpec.getIdentifier(),
"%s: conflict for determining a strategy for retrieval of (navigable) parent for class, "
+ "contains multiple annotations '@%s' having navigable=PARENT, while at most one is allowed.",
@@ -139,7 +140,8 @@ implements MetaModelRefiner {
if(!fieldEvaluator.getGetter(cls).isPresent()) {
- validationFailures.add(
+ validate.onFailure(
+ objectSpec,
objectSpec.getIdentifier(),
"%s: unable to determine a strategy for retrieval of (navigable) parent for class, "
+ "field '%s' annotated with '@%s' having navigable=PARENT does not provide a getter.",
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java
index 0128874..2f4b275 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java
@@ -38,8 +38,8 @@ import org.apache.isis.metamodel.spec.ObjectSpecification;
import org.apache.isis.metamodel.spec.feature.Contributed;
import org.apache.isis.metamodel.spec.feature.ObjectAction;
import org.apache.isis.metamodel.specloader.classsubstitutor.ClassSubstitutor;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
import lombok.val;
@@ -110,20 +110,23 @@ implements MetaModelRefiner, ObjectSpecIdFacetFactory {
@Override
public boolean visit(
ObjectSpecification objectSpec,
- ValidationFailures validationFailures) {
- validate(objectSpec, validationFailures);
+ MetaModelValidator validator) {
+
+ validate(objectSpec, validator);
return true;
}
private void validate(
ObjectSpecification objectSpec,
- ValidationFailures validationFailures) {
+ MetaModelValidator validator) {
+
if(skip(objectSpec)) {
return;
}
val objectSpecIdFacet = objectSpec.getFacet(ObjectSpecIdFacet.class);
if(objectSpecIdFacet instanceof ObjectSpecIdFacetDerivedFromClassName) {
- validationFailures.add(
+ validator.onFailure(
+ objectSpec,
objectSpec.getIdentifier(),
"%s: the object type must be specified explicitly ('%s' config property). "
+ "Defaulting the object type from the package/class/package name can lead "
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/recreatable/RecreatableObjectFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/recreatable/RecreatableObjectFacetFactory.java
index 412fa59..fb80a32 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/recreatable/RecreatableObjectFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/recreatable/RecreatableObjectFacetFactory.java
@@ -97,12 +97,13 @@ implements MetaModelRefiner, PostConstructMethodCache {
@Override
public void refineProgrammingModel(ProgrammingModel programmingModel) {
- programmingModel.addValidator((objectSpec, validationFailures) -> {
+ programmingModel.addValidator((objectSpec, validate) -> {
final ViewModelFacet facet = objectSpec.getFacet(ViewModelFacet.class);
final Facet underlyingFacet = facet != null ? facet.getUnderlyingFacet() : null;
if(underlyingFacet != null && underlyingFacet.getClass() != facet.getClass()) {
- validationFailures.add(
+ validate.onFailure(
+ objectSpec,
objectSpec.getIdentifier(),
"%s: has multiple incompatible annotations/interfaces indicating that " +
"it is a recreatable object of some sort (%s and %s)",
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java
index 531dd7c..5aa2e59 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java
@@ -149,7 +149,7 @@ implements MetaModelRefiner {
@Override
public void refineProgrammingModel(ProgrammingModel programmingModel) {
- programmingModel.addValidator((objectSpec, validationFailures) -> {
+ programmingModel.addValidator((objectSpec, validate) -> {
final Class<?> cls = objectSpec.getCorrespondingClass();
@@ -167,7 +167,8 @@ implements MetaModelRefiner {
final List<Method> methods = methodsWithTitleAnnotation(cls);
final List<Method> superClassMethods = methodsWithTitleAnnotation(supClass);
if (methods.size() > superClassMethods.size()) {
- validationFailures.add(
+ validate.onFailure(
+ objectSpec,
objectSpec.getIdentifier(),
"%s: conflict for determining a strategy for retrieval of title for class, contains a method '%s' and an annotation '@%s'",
objectSpec.getIdentifier().getClassName(),
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/properties/property/maxlength/MaxLengthFacetForMaxLengthAnnotationOnProperty.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/properties/property/maxlength/MaxLengthFacetForMaxLengthAnnotationOnProperty.java
deleted file mode 100644
index 500db0f..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/properties/property/maxlength/MaxLengthFacetForMaxLengthAnnotationOnProperty.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.metamodel.facets.properties.property.maxlength;
-
-import org.apache.isis.metamodel.facetapi.FacetHolder;
-import org.apache.isis.metamodel.facets.objectvalue.maxlen.MaxLengthFacetAbstract;
-
-/**
- * @deprecated
- */
-@Deprecated
-public class MaxLengthFacetForMaxLengthAnnotationOnProperty extends MaxLengthFacetAbstract {
-
- public MaxLengthFacetForMaxLengthAnnotationOnProperty(final int value, final FacetHolder holder) {
- super(value, holder);
- }
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/progmodel/ProgrammingModelService.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/progmodel/ProgrammingModelService.java
index 4dbbe8a..1c0cd8c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/progmodel/ProgrammingModelService.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/progmodel/ProgrammingModelService.java
@@ -18,14 +18,15 @@
*/
package org.apache.isis.metamodel.progmodel;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
-
/**
* @since 2.0
*/
public interface ProgrammingModelService {
+ /**
+ *
+ * @apiNote don't call this during '@PostConstruct' phase
+ */
ProgrammingModel getProgrammingModel();
- ValidationFailures getValidationResult();
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/ProgrammingModelServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/ProgrammingModelServiceDefault.java
index 7bc3741..7e2145e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/ProgrammingModelServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/ProgrammingModelServiceDefault.java
@@ -29,7 +29,6 @@ import org.apache.isis.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.metamodel.progmodel.ProgrammingModelInitFilter;
import org.apache.isis.metamodel.progmodel.ProgrammingModelService;
import org.apache.isis.metamodel.progmodels.dflt.ProgrammingModelFacetsJava8;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
import lombok.val;
import lombok.extern.log4j.Log4j2;
@@ -42,11 +41,6 @@ public class ProgrammingModelServiceDefault implements ProgrammingModelService {
return programmingModel.get();
}
- @Override
- public ValidationFailures getValidationResult() {
- return validationResult.get();
- }
-
// -- HELPER
@Inject private ServiceRegistry serviceRegistry;
@@ -55,9 +49,6 @@ public class ProgrammingModelServiceDefault implements ProgrammingModelService {
private _Lazy<ProgrammingModel> programmingModel =
_Lazy.threadSafe(this::createProgrammingModel);
- private _Lazy<ValidationFailures> validationResult =
- _Lazy.threadSafe(this::validate);
-
private ProgrammingModel createProgrammingModel() {
log.info("About to create the ProgrammingModel.");
@@ -95,13 +86,5 @@ public class ProgrammingModelServiceDefault implements ProgrammingModelService {
return programmingModel;
}
-
- private ValidationFailures validate() {
- val failures = new ValidationFailures();
- programmingModel.get().streamValidators()
- .forEach(validator->validator.validateInto(failures));
- return failures;
- }
-
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoader.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoader.java
index 867f8f4..6a90caa 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoader.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoader.java
@@ -28,6 +28,8 @@ import org.apache.isis.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.metamodel.spec.ObjectSpecId;
import org.apache.isis.metamodel.spec.ObjectSpecification;
import org.apache.isis.metamodel.specloader.specimpl.IntrospectionState;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
+import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
import lombok.val;
@@ -48,7 +50,14 @@ public interface SpecificationLoader {
*/
void disposeMetaModel();
- void validateMetaModel();
+ /**
+ * Returns the collected results of the various {@link MetaModelValidator}s configured with
+ * the {@link ProgrammingModel}.
+ *
+ * @apiNote Some of the {@link MetaModelValidator}s run during {@link #createMetaModel()},
+ * others are only triggered when calling this method.
+ */
+ ValidationFailures getValidationResult();
// -- LOOKUP
@@ -107,8 +116,6 @@ public interface SpecificationLoader {
return loadSpecification(className, null);
}
-
-
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoaderDefault.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoaderDefault.java
index 243eff7..92555ac 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoaderDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoaderDefault.java
@@ -29,6 +29,8 @@ import javax.inject.Inject;
import org.springframework.stereotype.Service;
+import org.apache.isis.commons.internal.base._Blackhole;
+import org.apache.isis.commons.internal.base._Lazy;
import org.apache.isis.commons.internal.base._Timing;
import org.apache.isis.commons.internal.collections._Lists;
import org.apache.isis.commons.internal.environment.IsisSystemEnvironment;
@@ -48,6 +50,7 @@ import org.apache.isis.metamodel.specloader.specimpl.FacetedMethodsBuilderContex
import org.apache.isis.metamodel.specloader.specimpl.IntrospectionState;
import org.apache.isis.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
import org.apache.isis.metamodel.specloader.specimpl.standalonelist.ObjectSpecificationOnStandaloneList;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorAbstract;
import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
import org.apache.isis.schema.utils.CommonDtoUtils;
@@ -122,7 +125,7 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
@Override
public void createMetaModel() {
- log.info("About to creating the Metamodel");
+ log.info("About to create the Metamodel ...");
// initialize subcomponents, only after @PostConstruct has globally completed
facetProcessor.init();
@@ -193,6 +196,9 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
log.info("Introspecting all cached specs up to {}", IntrospectionState.TYPE_AND_MEMBERS_INTROSPECTED);
introspect(cachedSpecifications, IntrospectionState.TYPE_AND_MEMBERS_INTROSPECTED);
}
+
+ log.info("Running remaining validators");
+ _Blackhole.consume(getValidationResult()); // as a side effect memoizes the validation result
stopWatch.stop();
log.info("createMetaModel() - took " + stopWatch);
@@ -200,16 +206,25 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
}
@Override
- public void validateMetaModel() {
+ public ValidationFailures getValidationResult() {
+ return validationResult.get();
+ }
+
+ private _Lazy<ValidationFailures> validationResult =
+ _Lazy.threadSafe(this::collectFailuresFromMetaModel);
+
+ private ValidationFailures collectFailuresFromMetaModel() {
val failures = new ValidationFailures();
programmingModel.streamValidators()
- .forEach(validator->validator.validateInto(failures));
- // return failures;
+ .map(MetaModelValidatorAbstract.class::cast)
+ .forEach(validator->validator.collectFailuresInto(failures));
+ return failures;
}
@Override
public void disposeMetaModel() {
cache.clear();
+ validationResult.clear();
log.info("Metamodel disposed.");
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidator.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidator.java
index 547cc6f..e0f1366 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidator.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidator.java
@@ -19,20 +19,26 @@
package org.apache.isis.metamodel.specloader.validator;
-import java.util.function.Consumer;
-
+import org.apache.isis.applib.Identifier;
import org.apache.isis.metamodel.facetapi.FacetHolder;
+import org.apache.isis.metamodel.facets.all.deficiencies.DeficiencyFacet;
+
+import lombok.NonNull;
+import lombok.val;
public interface MetaModelValidator {
- /**
- * Validate and then append any {@link ValidationFailure} to given validationFailures.
- *
- * @param validationFailures
- */
- //@Deprecated
- void validateInto(ValidationFailures validationFailures);
-
- //void validateInto(FacetHolder holder, Consumer<ValidationFailure> onFailure);
+ default void onFailure(
+ @NonNull FacetHolder facetHolder,
+ @NonNull Identifier deficiencyOrigin,
+ @NonNull String deficiencyMessageFormat,
+ Object ...args) {
+
+ val deficiencyMessage = String.format(deficiencyMessageFormat, args);
+
+ DeficiencyFacet.appendTo(facetHolder, deficiencyOrigin, deficiencyMessage);
+ }
+
+
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorAbstract.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorAbstract.java
index 5e11eec..80ac727 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorAbstract.java
@@ -19,7 +19,11 @@
package org.apache.isis.metamodel.specloader.validator;
+import org.apache.isis.applib.Identifier;
import org.apache.isis.metamodel.MetaModelContext;
+import org.apache.isis.metamodel.facetapi.FacetHolder;
+
+import lombok.NonNull;
public abstract class MetaModelValidatorAbstract
implements MetaModelValidator, MetaModelContext.Delegating {
@@ -28,5 +32,27 @@ implements MetaModelValidator, MetaModelContext.Delegating {
public MetaModelContext getMetaModelContext() {
return MetaModelContext.current();
}
+
+ protected final ValidationFailures failures = new ValidationFailures();
+
+ /**
+ * Collect any {@link ValidationFailure} to given validationFailures.
+ *
+ * @param validationFailures
+ */
+ public void collectFailuresInto(@NonNull ValidationFailures validationFailures) {
+ validationFailures.addAll(failures);
+ }
+
+ @Override
+ public void onFailure(
+ @NonNull FacetHolder facetHolder,
+ @NonNull Identifier deficiencyOrigin,
+ @NonNull String deficiencyMessageFormat,
+ Object... args) {
+
+ MetaModelValidator.super.onFailure(facetHolder, deficiencyOrigin, deficiencyMessageFormat, args);
+ failures.add(deficiencyOrigin, deficiencyMessageFormat, args);
+ }
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorComposite.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorComposite.java
deleted file mode 100644
index e81b208..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorComposite.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.metamodel.specloader.validator;
-
-import java.util.List;
-
-import org.apache.isis.commons.internal.collections._Lists;
-
-import lombok.val;
-
-@Deprecated
-final class MetaModelValidatorComposite extends MetaModelValidatorAbstract {
-
- private final List<MetaModelValidator> validators = _Lists.newArrayList();
-
- public MetaModelValidatorComposite add(MetaModelValidator validator) {
-
- if(validator instanceof MetaModelValidatorComposite) {
- // flatten the structure ... don't allow composites to contain composites,
- // such that the size() operation is a simple one
- val composite = (MetaModelValidatorComposite) validator;
- validators.addAll(composite.validators);
- } else {
- validators.add(validator);
- }
- return this;
- }
-
- public MetaModelValidatorComposite addAll(MetaModelValidator... validators) {
- for (val validator : validators) {
- add(validator);
- }
- return this;
- }
-
- @Override
- public void validateInto(ValidationFailures validationFailures) {
- for (val validator : validators) {
- validator.validateInto(validationFailures);
- }
- }
-
- public static MetaModelValidatorComposite asComposite(MetaModelValidator baseMetaModelValidator) {
- val metaModelValidatorComposite = new MetaModelValidatorComposite();
- metaModelValidatorComposite.add(baseMetaModelValidator);
- return metaModelValidatorComposite;
- }
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForConflictingOptionality.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForConflictingOptionality.java
index 66e077d..753f802 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForConflictingOptionality.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForConflictingOptionality.java
@@ -27,28 +27,21 @@ import lombok.val;
public class MetaModelValidatorForConflictingOptionality extends MetaModelValidatorAbstract {
- private final ValidationFailures failures = new ValidationFailures();
-
public MetaModelValidatorForConflictingOptionality() {
}
-
- @Override
- public void validateInto(final ValidationFailures validationFailures) {
- validationFailures.addAll(failures);
+
+ public Facet flagIfConflict(final MandatoryFacet facet, final String message) {
+ if(conflictingOptionality(facet)) {
+ addFailure(facet, message);
+ }
+ return facet;
}
private Facet addFailure(final Facet facet, final String message) {
if(facet != null) {
val holder = (IdentifiedHolder) facet.getFacetHolder();
val identifier = holder.getIdentifier();
- failures.add(identifier, message + ": " + identifier.toFullIdentityString());
- }
- return facet;
- }
-
- public Facet flagIfConflict(final MandatoryFacet facet, final String message) {
- if(conflictingOptionality(facet)) {
- addFailure(facet, message);
+ super.onFailure(holder, identifier, "%s : %s", message, identifier.toFullIdentityString());
}
return facet;
}
@@ -67,4 +60,6 @@ public class MetaModelValidatorForConflictingOptionality extends MetaModelValida
}
+
+
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForDeprecatedAbstract.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForDeprecatedAbstract.java
index 0511d6a..1953a7f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForDeprecatedAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForDeprecatedAbstract.java
@@ -26,8 +26,6 @@ import lombok.val;
public abstract class MetaModelValidatorForDeprecatedAbstract extends MetaModelValidatorAbstract {
- private final ValidationFailures failures = new ValidationFailures();
-
/**
* @param facet
*/
@@ -40,10 +38,12 @@ public abstract class MetaModelValidatorForDeprecatedAbstract extends MetaModelV
* @param processMethodContext - can be null if none available.
*/
public <T extends Facet> T flagIfPresent(T facet, FacetFactory.AbstractProcessWithMethodContext<?> processMethodContext) {
- if(facet != null) {
+ if(facet != null &&
+ !getConfiguration().getReflector().getValidator().isAllowDeprecated()) {
+
val holder = (IdentifiedHolder) facet.getFacetHolder();
val identifier = holder.getIdentifier();
- failures.add(identifier, failureMessageFor(facet, processMethodContext));
+ super.onFailure(holder, identifier, failureMessageFor(facet, processMethodContext));
}
return facet;
}
@@ -62,13 +62,6 @@ public abstract class MetaModelValidatorForDeprecatedAbstract extends MetaModelV
protected abstract String failureMessageFor(Facet facet, FacetFactory.AbstractProcessWithMethodContext<?> processMethodContext);
- @Override
- public void validateInto(ValidationFailures validationFailures) {
-
- if(getConfiguration().getReflector().getValidator().isAllowDeprecated()) {
- return;
- }
- validationFailures.addAll(failures);
- }
+
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForDeprecatedMethodPrefix.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForDeprecatedMethodPrefix.java
index d8acc84..9d83cdb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForDeprecatedMethodPrefix.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForDeprecatedMethodPrefix.java
@@ -32,7 +32,9 @@ public class MetaModelValidatorForDeprecatedMethodPrefix extends MetaModelValida
}
@Override
- protected String failureMessageFor(final Facet facet, final FacetFactory.AbstractProcessWithMethodContext processMethodContext) {
+ protected String failureMessageFor(
+ final Facet facet,
+ final FacetFactory.AbstractProcessWithMethodContext<?> processMethodContext) {
final boolean inherited = isInherited(processMethodContext);
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForValidationFailures.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForValidationFailures.java
index f53626a..67febcd 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForValidationFailures.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorForValidationFailures.java
@@ -27,19 +27,12 @@ import lombok.val;
public class MetaModelValidatorForValidationFailures extends MetaModelValidatorAbstract {
- private final ValidationFailures failures = new ValidationFailures();
-
public MetaModelValidatorForValidationFailures() {
}
- @Override
- public void validateInto(ValidationFailures validationFailures) {
- validationFailures.addAll(failures);
- }
-
- public void addFailure(Identifier identifier, String pattern, Object... arguments) {
- failures.add(identifier, pattern, arguments);
- }
+// public void addFailure(Identifier identifier, String pattern, Object... arguments) {
+// failures.add(identifier, pattern, arguments);
+// }
// public Facet addFailure(Facet facet, String message) {
// if(facet != null) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorVisiting.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorVisiting.java
index 48d19c8..3d752f2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorVisiting.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/MetaModelValidatorVisiting.java
@@ -27,6 +27,7 @@ import org.apache.isis.metamodel.spec.ObjectSpecification;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
+import lombok.val;
@RequiredArgsConstructor(staticName = "of")
public class MetaModelValidatorVisiting extends MetaModelValidatorAbstract {
@@ -36,41 +37,39 @@ public class MetaModelValidatorVisiting extends MetaModelValidatorAbstract {
/**
* @return <tt>true</tt> continue visiting specs.
*/
- boolean visit(ObjectSpecification objectSpec, ValidationFailures validationFailures);
+ boolean visit(ObjectSpecification objectSpec, MetaModelValidator validator);
}
public interface SummarizingVisitor extends Visitor {
- void summarize(ValidationFailures validationFailures);
+ void summarize(MetaModelValidator validator);
}
@NonNull private final Visitor visitor;
@Override
- public final void validateInto(ValidationFailures validationFailures) {
-
- validateAll(validationFailures);
-
- summarize(validationFailures);
+ public void collectFailuresInto(@NonNull ValidationFailures validationFailures) {
+ validateAll();
+ summarize();
+ super.collectFailuresInto(validationFailures);
}
- private void validateAll(final ValidationFailures validationFailures) {
+ private void validateAll() {
- final List<ObjectSpecification> specsValidated = _Lists.newArrayList();
+ val specsValidated = _Lists.<ObjectSpecification>newArrayList();
- while(validateSpecs(specsValidated, validationFailures)) {
+ while(validateSpecs(specsValidated)) {
// validate in a loop, because the act of validating might cause additional specs to be uncovered
}
}
- private boolean validateSpecs(
- final List<ObjectSpecification> specsAlreadyValidated,
- final ValidationFailures validationFailures) {
+ private boolean validateSpecs(List<ObjectSpecification> specsAlreadyValidated) {
// all currently known specs
// (previously we took a protective copy to avoid a concurrent modification exception,
// but this is now done by SpecificationLoader itself)
- final Collection<ObjectSpecification> specsToValidate = getSpecificationLoader().snapshotSpecifications();
+ final Collection<ObjectSpecification> specsToValidate =
+ getSpecificationLoader().snapshotSpecifications();
// don't validate any specs already processed
specsToValidate.removeAll(specsAlreadyValidated);
@@ -80,8 +79,8 @@ public class MetaModelValidatorVisiting extends MetaModelValidatorAbstract {
}
// validate anything new
- for (final ObjectSpecification objSpec : specsToValidate) {
- if(!visitor.visit(objSpec, validationFailures)) {
+ for (val objSpec : specsToValidate) {
+ if(!visitor.visit(objSpec, this)) {
break;
}
}
@@ -93,10 +92,10 @@ public class MetaModelValidatorVisiting extends MetaModelValidatorAbstract {
return true;
}
- private void summarize(final ValidationFailures validationFailures) {
+ private void summarize() {
if(visitor instanceof SummarizingVisitor) {
SummarizingVisitor summarizingVisitor = (SummarizingVisitor) visitor;
- summarizingVisitor.summarize(validationFailures);
+ summarizingVisitor.summarize(this);
}
}
diff --git a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java
index e63afb2..573a1ee 100644
--- a/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java
@@ -30,9 +30,11 @@ import org.apache.isis.commons.internal.context._Context;
import org.apache.isis.config.IsisConfiguration;
import org.apache.isis.config.internal._Config;
import org.apache.isis.metamodel.MetaModelContext;
+import org.apache.isis.metamodel.facetapi.FacetHolderImpl;
import org.apache.isis.metamodel.facets.FacetFactory;
import org.apache.isis.metamodel.progmodel.ProgrammingModelAbstract;
import org.apache.isis.metamodel.progmodel.ProgrammingModelInitFilterDefault;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorAbstract;
import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
import org.apache.isis.unittestsupport.jmocking.JUnitRuleMockery2;
@@ -59,12 +61,12 @@ public class ViewModelSemanticCheckingFacetFactoryTest {
facetFactory.refineProgrammingModel(programmingModel);
programmingModel.init(new ProgrammingModelInitFilterDefault());
- facetFactory.process(new FacetFactory.ProcessClassContext(cls, null, null));
+ facetFactory.process(new FacetFactory.ProcessClassContext(cls, null, new FacetHolderImpl()));
val validationFailures = new ValidationFailures();
programmingModel.streamValidators()
- .forEach(validator->validator.validateInto(validationFailures));
+ .forEach(validator->((MetaModelValidatorAbstract)validator).collectFailuresInto(validationFailures));
return validationFailures;
}
diff --git a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/JdoProgrammingModelPlugin.java b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/JdoProgrammingModelPlugin.java
index a54bb07..b714d1e 100644
--- a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/JdoProgrammingModelPlugin.java
+++ b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/JdoProgrammingModelPlugin.java
@@ -27,9 +27,10 @@ import javax.jdo.annotations.IdentityType;
import org.springframework.stereotype.Component;
-import org.apache.isis.applib.Identifier;
import org.apache.isis.commons.internal.collections._Lists;
import org.apache.isis.commons.internal.collections._Maps;
+import org.apache.isis.commons.internal.collections._Multimaps;
+import org.apache.isis.commons.internal.collections._Multimaps.ListMultimap;
import org.apache.isis.config.IsisConfiguration;
import org.apache.isis.jdo.metamodel.facets.object.datastoreidentity.JdoDatastoreIdentityAnnotationFacetFactory;
import org.apache.isis.jdo.metamodel.facets.object.discriminator.JdoDiscriminatorAnnotationFacetFactory;
@@ -53,8 +54,8 @@ import org.apache.isis.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.metamodel.progmodel.ProgrammingModel.Marker;
import org.apache.isis.metamodel.spec.ObjectSpecId;
import org.apache.isis.metamodel.spec.ObjectSpecification;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
import static org.apache.isis.commons.internal.base._NullSafe.stream;
@@ -121,7 +122,7 @@ public class JdoProgrammingModelPlugin implements MetaModelRefiner {
private void addValidatorToEnsureIdentityType() {
- pm.addValidator((objSpec, validationFailures) -> {
+ pm.addValidator((objSpec, validation) -> {
final JdoPersistenceCapableFacet jpcf = objSpec.getFacet(JdoPersistenceCapableFacet.class);
if(jpcf == null) {
@@ -141,7 +142,8 @@ public class JdoProgrammingModelPlugin implements MetaModelRefiner {
} else {
// in fact, at the time of writing there are no others, so this is theoretical in case there is
// a future change to the JDO spec
- validationFailures.add(
+ validation.onFailure(
+ objSpec,
objSpec.getIdentifier(),
"%s: is annotated with @PersistenceCapable but with an unrecognized identityType (%s)",
objSpec.getFullIdentifier(),
@@ -155,9 +157,10 @@ public class JdoProgrammingModelPlugin implements MetaModelRefiner {
private void addValidatorToCheckForUnsupportedAnnotations() {
- pm.addValidator((objSpec, validationFailures) -> {
+ pm.addValidator((objSpec, validation) -> {
if (objSpec.containsDoOpFacet(ParentedCollectionFacet.class) && !objSpec.containsDoOpFacet(CollectionFacet.class)) {
- validationFailures.add(
+ validation.onFailure(
+ objSpec,
objSpec.getIdentifier(),
"%s: DataNucleus object store currently does not supported Aggregated or EmbeddedOnly annotations",
objSpec.getFullIdentifier());
@@ -169,34 +172,37 @@ public class JdoProgrammingModelPlugin implements MetaModelRefiner {
private void addValidatorToEnsureUniqueObjectIds() {
- final Map<ObjectSpecId, List<ObjectSpecification>> specsById = _Maps.newHashMap();
+ final ListMultimap<ObjectSpecId, ObjectSpecification> collidingSpecsById =
+ _Multimaps.newListMultimap();
- MetaModelValidatorVisiting.SummarizingVisitor ensureUniqueObjectIds = new MetaModelValidatorVisiting.SummarizingVisitor(){
+ final MetaModelValidatorVisiting.SummarizingVisitor ensureUniqueObjectIds =
+ new MetaModelValidatorVisiting.SummarizingVisitor(){
@Override
- public boolean visit(ObjectSpecification objSpec, ValidationFailures validationFailures) {
- ObjectSpecId specId = objSpec.getSpecId();
- List<ObjectSpecification> objectSpecifications = specsById.get(specId);
- if(objectSpecifications == null) {
- objectSpecifications = _Lists.newArrayList();
- specsById.put(specId, objectSpecifications);
- }
- objectSpecifications.add(objSpec);
+ public boolean visit(ObjectSpecification objSpec, MetaModelValidator validator) {
+ val specId = objSpec.getSpecId();
+ collidingSpecsById.putElement(specId, objSpec);
return true;
}
@Override
- public void summarize(final ValidationFailures validationFailures) {
- for (final ObjectSpecId specId : specsById.keySet()) {
- val specList = specsById.get(specId);
- int numSpecs = specList.size();
- if(numSpecs > 1) {
- val csv = asCsv(specList);
- validationFailures.add(
- Identifier.classIdentifier(specId.asString()),
- "Object type '%s' mapped to multiple classes: %s",
- specId.asString(),
- csv);
+ public void summarize(MetaModelValidator validator) {
+ for (val specId : collidingSpecsById.keySet()) {
+ val collidingSpecs = collidingSpecsById.get(specId);
+ val isCollision = collidingSpecs.size()>1;
+ if(isCollision) {
+ val csv = asCsv(collidingSpecs);
+
+ collidingSpecs.forEach(spec->{
+ validator.onFailure(
+ spec,
+ spec.getIdentifier(),
+ "Object type '%s' mapped to multiple classes: %s",
+ specId.asString(),
+ csv);
+ });
+
+
}
}
}
@@ -219,7 +225,7 @@ public class JdoProgrammingModelPlugin implements MetaModelRefiner {
MetaModelValidatorVisiting.SummarizingVisitor visitor = new MetaModelValidatorVisiting.SummarizingVisitor(){
@Override
- public boolean visit(ObjectSpecification objSpec, ValidationFailures validationFailures) {
+ public boolean visit(ObjectSpecification objSpec, MetaModelValidator validator) {
Class<?> correspondingClass = objSpec.getCorrespondingClass();
if(correspondingClass == null) {
return true;
@@ -248,7 +254,7 @@ public class JdoProgrammingModelPlugin implements MetaModelRefiner {
}
@Override
- public void summarize(final ValidationFailures validationFailures) {
+ public void summarize(final MetaModelValidator validator) {
//FIXME[2112] module (legacy) specific, remove?
// final Set<String> modulePackageNames = modulePackageNamesFrom(appManifest);
//
diff --git a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/query/VisitorForClauseAbstract.java b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/query/VisitorForClauseAbstract.java
index 6f32389..95873bc 100644
--- a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/query/VisitorForClauseAbstract.java
+++ b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/query/VisitorForClauseAbstract.java
@@ -23,8 +23,8 @@ import java.util.List;
import org.apache.isis.applib.Identifier;
import org.apache.isis.metamodel.spec.ObjectSpecification;
import org.apache.isis.metamodel.specloader.SpecificationLoader;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
abstract class VisitorForClauseAbstract implements MetaModelValidatorVisiting.Visitor {
@@ -34,6 +34,7 @@ abstract class VisitorForClauseAbstract implements MetaModelValidatorVisiting.Vi
VisitorForClauseAbstract(
final JdoQueryAnnotationFacetFactory facetFactory,
final String clause) {
+
this.facetFactory = facetFactory;
this.clause = clause;
}
@@ -41,14 +42,16 @@ abstract class VisitorForClauseAbstract implements MetaModelValidatorVisiting.Vi
@Override
public boolean visit(
final ObjectSpecification objectSpec,
- final ValidationFailures validationFailures) {
- validate(objectSpec, validationFailures);
+ final MetaModelValidator validator) {
+
+ validate(objectSpec, validator);
return true;
}
private void validate(
final ObjectSpecification objectSpec,
- final ValidationFailures validationFailures) {
+ final MetaModelValidator validator) {
+
final JdoQueryFacet facet = objectSpec.getFacet(JdoQueryFacet.class);
if(facet == null) {
return;
@@ -58,7 +61,7 @@ abstract class VisitorForClauseAbstract implements MetaModelValidatorVisiting.Vi
if(namedQuery.getLanguage().equals("JDOQL")) {
final String query = namedQuery.getQuery();
final String fromClassName = deriveClause(query);
- interpretJdoql(fromClassName, objectSpec, query, validationFailures);
+ interpretJdoql(fromClassName, objectSpec, query, validator);
}
}
}
@@ -67,7 +70,7 @@ abstract class VisitorForClauseAbstract implements MetaModelValidatorVisiting.Vi
final String classNameFromClause,
final ObjectSpecification objectSpec,
final String query,
- final ValidationFailures validationFailures) {
+ final MetaModelValidator validator) {
if (classNameFromClause == null) {
return;
@@ -75,14 +78,15 @@ abstract class VisitorForClauseAbstract implements MetaModelValidatorVisiting.Vi
final String className = objectSpec.getCorrespondingClass().getName();
if (getSpecificationLoader().loadSpecification(classNameFromClause)==null) {
- validationFailures.add(
+ validator.onFailure(
+ objectSpec,
Identifier.classIdentifier(className),
"%s: error in JDOQL query, class name for '%s' clause not recognized (JDOQL : %s)",
className, clause, query);
return;
}
- postInterpretJdoql(classNameFromClause, objectSpec, query, validationFailures);
+ postInterpretJdoql(classNameFromClause, objectSpec, query, validator);
}
abstract String deriveClause(final String query);
@@ -91,7 +95,7 @@ abstract class VisitorForClauseAbstract implements MetaModelValidatorVisiting.Vi
final String classNameFromClause,
final ObjectSpecification objectSpec,
final String query,
- final ValidationFailures validationFailures);
+ final MetaModelValidator validator);
SpecificationLoader getSpecificationLoader() {
diff --git a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/query/VisitorForFromClause.java b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/query/VisitorForFromClause.java
index ffe3eb3..92df70a 100644
--- a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/query/VisitorForFromClause.java
+++ b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/query/VisitorForFromClause.java
@@ -23,7 +23,7 @@ import java.util.Objects;
import org.apache.isis.applib.Identifier;
import org.apache.isis.metamodel.spec.Hierarchical;
import org.apache.isis.metamodel.spec.ObjectSpecification;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
import lombok.val;
@@ -44,7 +44,7 @@ class VisitorForFromClause extends VisitorForClauseAbstract {
final String classNameFromClause,
final ObjectSpecification objectSpec,
final String query,
- final ValidationFailures validationFailures) {
+ final MetaModelValidator validator) {
val className = objectSpec.getCorrespondingClass().getName();
if (Objects.equals(classNameFromClause, className)) {
@@ -55,7 +55,8 @@ class VisitorForFromClause extends VisitorForClauseAbstract {
if(subclasses.contains(objectSpec)) {
return;
}
- validationFailures.add(
+ validator.onFailure(
+ objectSpec,
Identifier.classIdentifier(className),
"%s: error in JDOQL query, class name after '%s' clause should be same as class name on which annotated, or one of its supertypes (JDOQL : %s)",
className, clause, query);
diff --git a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/query/VisitorForVariablesClause.java b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/query/VisitorForVariablesClause.java
index 24118ec..5a608c5 100644
--- a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/query/VisitorForVariablesClause.java
+++ b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/query/VisitorForVariablesClause.java
@@ -22,7 +22,7 @@ import org.apache.isis.applib.Identifier;
import org.apache.isis.jdo.metamodel.facets.object.persistencecapable.JdoPersistenceCapableFacet;
import org.apache.isis.metamodel.spec.ObjectSpecification;
import org.apache.isis.metamodel.specloader.specimpl.IntrospectionState;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
class VisitorForVariablesClause extends VisitorForClauseAbstract {
@@ -40,7 +40,7 @@ class VisitorForVariablesClause extends VisitorForClauseAbstract {
final String classNameFromClause,
final ObjectSpecification objectSpec,
final String query,
- final ValidationFailures validationFailures) {
+ final MetaModelValidator validator) {
final String className = objectSpec.getCorrespondingClass().getName();
@@ -51,7 +51,8 @@ class VisitorForVariablesClause extends VisitorForClauseAbstract {
objectSpecification.getFacet(JdoPersistenceCapableFacet.class);
if(persistenceCapableFacet == null) {
- validationFailures.add(
+ validator.onFailure(
+ objectSpec,
Identifier.classIdentifier(className),
"%s: error in JDOQL query, class name for '%s' clause is not annotated as @PersistenceCapable (JDOQL : %s)",
className, clause, query);
diff --git a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactory.java b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactory.java
index fb5a804..5435c25 100644
--- a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactory.java
+++ b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactory.java
@@ -29,9 +29,9 @@ import org.apache.isis.metamodel.facets.Annotations;
import org.apache.isis.metamodel.facets.FacetFactoryAbstract;
import org.apache.isis.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.metamodel.spec.ObjectSpecification;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting.Visitor;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
public class JdoVersionAnnotationFacetFactory extends FacetFactoryAbstract
implements MetaModelRefiner {
@@ -66,12 +66,12 @@ implements MetaModelRefiner {
return new MetaModelValidatorVisiting.Visitor() {
@Override
- public boolean visit(ObjectSpecification objectSpec, ValidationFailures validationFailures) {
- validate(objectSpec, validationFailures);
+ public boolean visit(ObjectSpecification objectSpec, MetaModelValidator validator) {
+ validate(objectSpec, validator);
return true;
}
- private void validate(ObjectSpecification objectSpec, ValidationFailures validationFailures) {
+ private void validate(ObjectSpecification objectSpec, MetaModelValidator validator) {
if(!declaresVersionAnnotation(objectSpec)) {
return;
}
@@ -79,7 +79,8 @@ implements MetaModelRefiner {
ObjectSpecification superclassSpec = objectSpec.superclass();
while(superclassSpec != null) {
if(declaresVersionAnnotation(superclassSpec)) {
- validationFailures.add(
+ validator.onFailure(
+ objectSpec,
objectSpec.getIdentifier(),
"%s: cannot have @Version annotated on this subclass and any of its supertypes; superclass: %s",
objectSpec.getFullIdentifier(),
diff --git a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/prop/column/BigDecimalDerivedFromJdoColumnAnnotationFacetFactory.java b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/prop/column/BigDecimalDerivedFromJdoColumnAnnotationFacetFactory.java
index e8a37ae..8e50b77 100644
--- a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/prop/column/BigDecimalDerivedFromJdoColumnAnnotationFacetFactory.java
+++ b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/prop/column/BigDecimalDerivedFromJdoColumnAnnotationFacetFactory.java
@@ -38,9 +38,9 @@ import org.apache.isis.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.metamodel.spec.ObjectSpecification;
import org.apache.isis.metamodel.spec.feature.Contributed;
import org.apache.isis.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting.Visitor;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
import lombok.val;
@@ -112,12 +112,12 @@ implements MetaModelRefiner {
return new MetaModelValidatorVisiting.Visitor() {
@Override
- public boolean visit(ObjectSpecification objectSpec, ValidationFailures validationFailures) {
- validate(objectSpec, validationFailures);
+ public boolean visit(ObjectSpecification objectSpec, MetaModelValidator validator) {
+ validate(objectSpec, validator);
return true;
}
- private void validate(ObjectSpecification objectSpec, ValidationFailures validationFailures) {
+ private void validate(ObjectSpecification objectSpec, MetaModelValidator validator) {
// only consider persistent entities
final JdoPersistenceCapableFacet pcFacet = objectSpec.getFacet(JdoPersistenceCapableFacet.class);
@@ -132,12 +132,12 @@ implements MetaModelRefiner {
// skip checks if annotated with JDO @NotPersistent
.filter(association->!association.containsDoOpFacet(JdoNotPersistentFacet.class))
.forEach(association->{
- validateBigDecimalValueFacet(association, validationFailures);
+ validateBigDecimalValueFacet(association, validator);
});
}
- private void validateBigDecimalValueFacet(ObjectAssociation association, ValidationFailures validationFailures) {
+ private void validateBigDecimalValueFacet(ObjectAssociation association, MetaModelValidator validator) {
BigDecimalValueFacet facet = association.getFacet(BigDecimalValueFacet.class);
if(facet == null) {
return;
@@ -153,14 +153,16 @@ implements MetaModelRefiner {
if(underlying instanceof BigDecimalFacetOnPropertyFromJavaxValidationDigitsAnnotation) {
if(notNullButNotEqual(facet.getPrecision(), underlying.getPrecision())) {
- validationFailures.add(
+ validator.onFailure(
+ association,
association.getIdentifier(),
"%s: @javax.jdo.annotations.Column(length=...) different from @javax.validation.constraint.Digits(...); should equal the sum of its integer and fraction attributes",
association.getIdentifier().toClassAndNameIdentityString());
}
if(notNullButNotEqual(facet.getScale(), underlying.getScale())) {
- validationFailures.add(
+ validator.onFailure(
+ association,
association.getIdentifier(),
"%s: @javax.jdo.annotations.Column(scale=...) different from @javax.validation.constraint.Digits(fraction=...)",
association.getIdentifier().toClassAndNameIdentityString());
diff --git a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java
index 7a9b710..718f865 100644
--- a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java
+++ b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java
@@ -40,9 +40,9 @@ import org.apache.isis.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.metamodel.spec.ObjectSpecification;
import org.apache.isis.metamodel.spec.feature.Contributed;
import org.apache.isis.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting.Visitor;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
import lombok.val;
@@ -122,12 +122,12 @@ implements MetaModelRefiner {
return new MetaModelValidatorVisiting.Visitor() {
@Override
- public boolean visit(ObjectSpecification objectSpec, ValidationFailures validationFailures) {
- validate(objectSpec, validationFailures);
+ public boolean visit(ObjectSpecification objectSpec, MetaModelValidator validator) {
+ validate(objectSpec, validator);
return true;
}
- private void validate(ObjectSpecification objectSpec, ValidationFailures validationFailures) {
+ private void validate(ObjectSpecification objectSpec, MetaModelValidator validator) {
final JdoPersistenceCapableFacet pcFacet = objectSpec.getFacet(JdoPersistenceCapableFacet.class);
if(pcFacet==null || pcFacet.getIdentityType() == IdentityType.NONDURABLE) {
@@ -141,10 +141,10 @@ implements MetaModelRefiner {
associations
// skip checks if annotated with JDO @NotPersistent
.filter(association->!association.containsDoOpFacet(JdoNotPersistentFacet.class))
- .forEach(association->validateMandatoryFacet(association, validationFailures));
+ .forEach(association->validateMandatoryFacet(association, validator));
}
- private void validateMandatoryFacet(ObjectAssociation association, ValidationFailures validationFailures) {
+ private void validateMandatoryFacet(ObjectAssociation association, MetaModelValidator validator) {
MandatoryFacet facet = association.getFacet(MandatoryFacet.class);
MandatoryFacet underlying = (MandatoryFacet) facet.getUnderlyingFacet();
@@ -155,7 +155,8 @@ implements MetaModelRefiner {
if(facet instanceof MandatoryFacetDerivedFromJdoColumn) {
if(association.isNotPersisted()) {
- validationFailures.add(
+ validator.onFailure(
+ association,
association.getIdentifier(),
"%s: @javax.jdo.annotations.Column found on non-persisted property; please remove)",
association.getIdentifier().toClassAndNameIdentityString());
@@ -168,12 +169,14 @@ implements MetaModelRefiner {
if(underlying.isInvertedSemantics()) {
// ie @Optional
- validationFailures.add(
+ validator.onFailure(
+ association,
association.getIdentifier(),
"%s: incompatible usage of Isis' @Optional annotation and @javax.jdo.annotations.Column; use just @javax.jdo.annotations.Column(allowsNull=\"...\")",
association.getIdentifier().toClassAndNameIdentityString());
} else {
- validationFailures.add(
+ validator.onFailure(
+ association,
association.getIdentifier(),
"%s: incompatible Isis' default of required/optional properties vs JDO; add @javax.jdo.annotations.Column(allowsNull=\"...\")",
association.getIdentifier().toClassAndNameIdentityString());
@@ -192,12 +195,14 @@ implements MetaModelRefiner {
}
if(underlying.isInvertedSemantics()) {
// ie @Optional
- validationFailures.add(
+ validator.onFailure(
+ association,
association.getIdentifier(),
"%s: incompatible usage of Isis' @Optional annotation and @javax.jdo.annotations.Column; use just @javax.jdo.annotations.Column(allowsNull=\"...\")",
association.getIdentifier().toClassAndNameIdentityString());
} else {
- validationFailures.add(
+ validator.onFailure(
+ association,
association.getIdentifier(),
"%s: incompatible default handling of required/optional properties between Isis and JDO; add @javax.jdo.annotations.Column(allowsNull=\"...\")",
association.getIdentifier().toClassAndNameIdentityString());
diff --git a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/prop/column/MaxLengthDerivedFromJdoColumnAnnotationFacetFactory.java b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/prop/column/MaxLengthDerivedFromJdoColumnAnnotationFacetFactory.java
index 956096e..8361ff2 100644
--- a/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/prop/column/MaxLengthDerivedFromJdoColumnAnnotationFacetFactory.java
+++ b/core/plugins/jdo/common/src/main/java/org/apache/isis/jdo/metamodel/facets/prop/column/MaxLengthDerivedFromJdoColumnAnnotationFacetFactory.java
@@ -32,15 +32,14 @@ import org.apache.isis.metamodel.facetapi.MetaModelRefiner;
import org.apache.isis.metamodel.facets.FacetFactoryAbstract;
import org.apache.isis.metamodel.facets.FacetedMethod;
import org.apache.isis.metamodel.facets.objectvalue.maxlen.MaxLengthFacet;
-import org.apache.isis.metamodel.facets.properties.property.maxlength.MaxLengthFacetForMaxLengthAnnotationOnProperty;
import org.apache.isis.metamodel.facets.properties.property.maxlength.MaxLengthFacetForPropertyAnnotation;
import org.apache.isis.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.metamodel.spec.ObjectSpecification;
import org.apache.isis.metamodel.spec.feature.Contributed;
import org.apache.isis.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting.Visitor;
-import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
import lombok.val;
@@ -98,12 +97,12 @@ implements MetaModelRefiner {
return new MetaModelValidatorVisiting.Visitor() {
@Override
- public boolean visit(ObjectSpecification objectSpec, ValidationFailures validationFailures) {
- validate(objectSpec, validationFailures);
+ public boolean visit(ObjectSpecification objectSpec, MetaModelValidator validator) {
+ validate(objectSpec, validator);
return true;
}
- private void validate(ObjectSpecification objectSpec, ValidationFailures validationFailures) {
+ private void validate(ObjectSpecification objectSpec, MetaModelValidator validator) {
final JdoPersistenceCapableFacet pcFacet = objectSpec.getFacet(JdoPersistenceCapableFacet.class);
if(pcFacet==null || pcFacet.getIdentityType() == IdentityType.NONDURABLE) {
@@ -126,17 +125,19 @@ implements MetaModelRefiner {
return;
}
- if(facet instanceof MaxLengthFacetDerivedFromJdoColumn && underlying instanceof MaxLengthFacetForMaxLengthAnnotationOnProperty) {
- if(facet.value() != underlying.value()) {
- validationFailures.add(
- association.getIdentifier(),
- "%s: inconsistent lengths specified in Isis' @MaxLength(...) and @javax.jdo.annotations.Column(length=...); use just @javax.jdo.annotations.Column(length=...)",
- association.getIdentifier().toClassAndNameIdentityString());
- }
- }
+// if(facet instanceof MaxLengthFacetDerivedFromJdoColumn && underlying instanceof MaxLengthFacetForMaxLengthAnnotationOnProperty) {
+// if(facet.value() != underlying.value()) {
+// validator.onFailure(
+// association,
+// association.getIdentifier(),
+// "%s: inconsistent lengths specified in Isis' @MaxLength(...) and @javax.jdo.annotations.Column(length=...); use just @javax.jdo.annotations.Column(length=...)",
+// association.getIdentifier().toClassAndNameIdentityString());
+// }
+// }
if(facet instanceof MaxLengthFacetDerivedFromJdoColumn && underlying instanceof MaxLengthFacetForPropertyAnnotation) {
if(facet.value() != underlying.value()) {
- validationFailures.add(
+ validator.onFailure(
+ association,
association.getIdentifier(),
"%s: inconsistent lengths specified in Isis' @Property(maxLength=...) and @javax.jdo.annotations.Column(length=...); use just @javax.jdo.annotations.Column(length=...)",
association.getIdentifier().toClassAndNameIdentityString());
diff --git a/core/plugins/jdo/common/src/test/java/org/apache/isis/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactoryTest_refineMetaModel.java b/core/plugins/jdo/common/src/test/java/org/apache/isis/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactoryTest_refineMetaModel.java
index 9ae60b6..1195be8 100644
--- a/core/plugins/jdo/common/src/test/java/org/apache/isis/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactoryTest_refineMetaModel.java
+++ b/core/plugins/jdo/common/src/test/java/org/apache/isis/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactoryTest_refineMetaModel.java
@@ -27,7 +27,10 @@ import org.junit.Rule;
import org.junit.Test;
import org.apache.isis.applib.Identifier;
+import org.apache.isis.metamodel.facets.all.deficiencies.DeficiencyFacet;
import org.apache.isis.metamodel.spec.ObjectSpecification;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidator;
+import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorAbstract;
import org.apache.isis.metamodel.specloader.validator.MetaModelValidatorVisiting.Visitor;
import org.apache.isis.metamodel.specloader.validator.ValidationFailures;
import org.apache.isis.unittestsupport.jmocking.JUnitRuleMockery2;
@@ -46,7 +49,8 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
private ObjectSpecification mockGrandParentType;
private Visitor newValidatorVisitor;
- private ValidationFailures validationFailures;
+ private ValidationFailures failures;
+ private MetaModelValidator validator;
private Sequence sequence;
@@ -58,7 +62,8 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
sequence = context.sequence("inorder");
- validationFailures = new ValidationFailures();
+ failures = new ValidationFailures();
+ validator = new MetaModelValidatorAbstract() {};
newValidatorVisitor = new JdoVersionAnnotationFacetFactory().newValidatorVisitor();
}
@@ -74,9 +79,9 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
}
});
- newValidatorVisitor.visit(mockChildType, validationFailures);
+ newValidatorVisitor.visit(mockChildType, validator);
- assertThat(validationFailures.getNumberOfFailures(), is(0));
+ assertThat(failures.getNumberOfFailures(), is(0));
}
@Test
@@ -97,9 +102,9 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
}
});
- newValidatorVisitor.visit(mockChildType, validationFailures);
+ newValidatorVisitor.visit(mockChildType, validator);
- assertThat(validationFailures.getNumberOfFailures(), is(0));
+ assertThat(failures.getNumberOfFailures(), is(0));
}
@Test
@@ -130,9 +135,9 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
}
});
- newValidatorVisitor.visit(mockChildType, validationFailures);
+ newValidatorVisitor.visit(mockChildType, validator);
- assertThat(validationFailures.getNumberOfFailures(), is(0));
+ assertThat(failures.getNumberOfFailures(), is(0));
}
@@ -171,15 +176,17 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
inSequence(sequence);
will(returnValue("mockParentType"));
+ oneOf(mockChildType).getFacet(DeficiencyFacet.class);
+ will(returnValue(null));
}
});
- newValidatorVisitor.visit(mockChildType, validationFailures);
+ newValidatorVisitor.visit(mockChildType, validator);
- assertThat(validationFailures.getNumberOfFailures(), is(1));
- assertThat(validationFailures.getMessages().iterator().next(), is("mockChildType: cannot have @Version annotated on this subclass and any of its supertypes; superclass: mockParentType"));
+ assertThat(failures.getNumberOfFailures(), is(1));
+ assertThat(failures.getMessages().iterator().next(), is("mockChildType: cannot have @Version annotated on this subclass and any of its supertypes; superclass: mockParentType"));
}
@@ -232,10 +239,10 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
}
});
- newValidatorVisitor.visit(mockChildType, validationFailures);
+ newValidatorVisitor.visit(mockChildType, validator);
- assertThat(validationFailures.getNumberOfFailures(), is(1));
- assertThat(validationFailures.getMessages().iterator().next(), is("mockChildType: cannot have @Version annotated on this subclass and any of its supertypes; superclass: mockGrandParentType"));
+ assertThat(failures.getNumberOfFailures(), is(1));
+ assertThat(failures.getMessages().iterator().next(), is("mockChildType: cannot have @Version annotated on this subclass and any of its supertypes; superclass: mockGrandParentType"));
}
}
diff --git a/core/runtime/src/main/java/org/apache/isis/runtime/system/session/IsisSessionFactoryDefault.java b/core/runtime/src/main/java/org/apache/isis/runtime/system/session/IsisSessionFactoryDefault.java
index 936c9d7..dffc810 100644
--- a/core/runtime/src/main/java/org/apache/isis/runtime/system/session/IsisSessionFactoryDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/runtime/system/session/IsisSessionFactoryDefault.java
@@ -89,7 +89,7 @@ public class IsisSessionFactoryDefault implements IsisSessionFactory {
val taskList = _ConcurrentTaskList.named("IsisSessionFactoryDefault Init")
- .addRunnable("SpecificationLoader::createThenValidateMetaModel", this::createThenValidateMetaModel)
+ .addRunnable("SpecificationLoader::createMetaModel", specificationLoader::createMetaModel)
.addRunnable("ChangesDtoUtils::init", ChangesDtoUtils::init)
.addRunnable("InteractionDtoUtils::init", InteractionDtoUtils::init)
.addRunnable("CommandDtoUtils::init", CommandDtoUtils::init)
@@ -103,11 +103,6 @@ public class IsisSessionFactoryDefault implements IsisSessionFactory {
}
- private void createThenValidateMetaModel() {
- specificationLoader.createMetaModel();
- specificationLoader.validateMetaModel();
- }
-
@PreDestroy
public void shutdown() {
// call might originate from a different thread than main
diff --git a/core/testsupport/integtestsupport/src/main/java/org/apache/isis/integtestsupport/validate/ValidateDomainModel.java b/core/testsupport/integtestsupport/src/main/java/org/apache/isis/integtestsupport/validate/ValidateDomainModel.java
index c825ade..1ee1a2a 100644
--- a/core/testsupport/integtestsupport/src/main/java/org/apache/isis/integtestsupport/validate/ValidateDomainModel.java
+++ b/core/testsupport/integtestsupport/src/main/java/org/apache/isis/integtestsupport/validate/ValidateDomainModel.java
@@ -54,10 +54,8 @@ public class ValidateDomainModel implements Runnable {
val specificationLoader = IsisContext.getSpecificationLoader();
- val programmingModelService = IsisContext.getServiceRegistry()
- .lookupServiceElseFail(ProgrammingModelService.class);
- this.validationFailures = programmingModelService.getValidationResult();
-
+ this.validationFailures = specificationLoader.getValidationResult();
+
val objectSpecifications = specificationLoader.snapshotSpecifications();
diff --git a/examples/smoketests/src/test/java/org/apache/isis/testdomain/domainmodel/SpecloaderPerformanceTest.java b/examples/smoketests/src/test/java/org/apache/isis/testdomain/domainmodel/SpecloaderPerformanceTest.java
index 1f2c6c2..0262253 100644
--- a/examples/smoketests/src/test/java/org/apache/isis/testdomain/domainmodel/SpecloaderPerformanceTest.java
+++ b/examples/smoketests/src/test/java/org/apache/isis/testdomain/domainmodel/SpecloaderPerformanceTest.java
@@ -66,8 +66,8 @@ class SpecloaderPerformanceTest {
IsisBeanTypeRegistry.repeatedTesting = true;
}
- static long ITERATIONS = 400; /* should typically run in ~10s */
- static long EXPECTED_MILLIS_PER_ITERATION = 500;
+ static long ITERATIONS = 100; /* should typically run in ~10s */
+ static long EXPECTED_MILLIS_PER_ITERATION = 100;
@Test
void repeatedConcurrentSpecloading_shouldNotDeadlock() {
diff --git a/extensions/incubator/src/main/java/org/apache/isis/metamodel/facets/actions/support/SupportingMethodValidatorRefinerFactory.java b/extensions/incubator/src/main/java/org/apache/isis/metamodel/facets/actions/support/SupportingMethodValidatorRefinerFactory.java
index e3d613f..5a7d55a 100644
--- a/extensions/incubator/src/main/java/org/apache/isis/metamodel/facets/actions/support/SupportingMethodValidatorRefinerFactory.java
+++ b/extensions/incubator/src/main/java/org/apache/isis/metamodel/facets/actions/support/SupportingMethodValidatorRefinerFactory.java
@@ -88,7 +88,8 @@ implements MetaModelRefiner {
val messageFormat = "%s#%s: has annotion %s, is assumed to support "
+ "a property, collection or action. Unmet constraint(s): %s";
- validationFailures.add(
+ validationFailures.onFailure(
+ spec,
spec.getIdentifier(),
messageFormat,
spec.getIdentifier().getClassName(),