You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2016/06/14 06:23:26 UTC
[5/5] isis git commit: ISIS-1418: allows @Nullable to be annotated on
either properties or parameters.
ISIS-1418: allows @Nullable to be annotated on either properties or parameters.
The appropriate facet is installed, and a MetaModelValidator is used to check that there are no conflicting annotations (ie @Mandatory vs @Nullable vs @Optional vs @Property#optionality or @Parameter#optionality).
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/7dd5042d
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/7dd5042d
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/7dd5042d
Branch: refs/heads/ISIS-1427
Commit: 7dd5042d117cbd55a6af3ba52c0f0a4c9ce27bb4
Parents: bd447a2
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Tue Jun 14 07:15:44 2016 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Tue Jun 14 07:15:44 2016 +0100
----------------------------------------------------------------------
.../isis/core/commons/lang/ArrayExtensions.java | 8 +--
.../isis/core/metamodel/facets/Annotations.java | 1 +
.../ParameterAnnotationFacetFactory.java | 34 +++++++---
...InvertedByNullableAnnotationOnParameter.java | 53 ++++++++++++++++
.../PropertyAnnotationFacetFactory.java | 43 +++++++++----
...tInvertedByNullableAnnotationOnProperty.java | 55 ++++++++++++++++
.../validator/MetaModelValidatorAbstract.java | 2 -
...ModelValidatorForConflictingOptionality.java | 66 ++++++++++++++++++++
...toryFromJdoColumnAnnotationFacetFactory.java | 2 +-
9 files changed, 239 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/7dd5042d/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ArrayExtensions.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ArrayExtensions.java b/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ArrayExtensions.java
index dfc692d..f4b611c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ArrayExtensions.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ArrayExtensions.java
@@ -123,10 +123,10 @@ public final class ArrayExtensions {
return list;
}
- public static <T> T coalesce(final T... strings) {
- for (final T str : strings) {
- if (str != null) {
- return str;
+ public static <T> T coalesce(final T... objects) {
+ for (final T object : objects) {
+ if (object != null) {
+ return object;
}
}
return null;
http://git-wip-us.apache.org/repos/asf/isis/blob/7dd5042d/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java
index aa17a4c..f1e2d40 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java
@@ -280,6 +280,7 @@ public final class Annotations {
Collection.class,
CollectionLayout.class,
MemberOrder.class,
+ javax.annotation.Nullable.class,
Title.class,
javax.jdo.annotations.Column.class
)
http://git-wip-us.apache.org/repos/asf/isis/blob/7dd5042d/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java
index 4518e94..a54bd02 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java
@@ -22,6 +22,8 @@ package org.apache.isis.core.metamodel.facets.param.parameter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
+import javax.annotation.Nullable;
+
import org.apache.isis.applib.annotation.MaxLength;
import org.apache.isis.applib.annotation.MustSatisfy;
import org.apache.isis.applib.annotation.Optional;
@@ -35,9 +37,11 @@ import org.apache.isis.core.metamodel.facetapi.MetaModelValidatorRefiner;
import org.apache.isis.core.metamodel.facets.Annotations;
import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
import org.apache.isis.core.metamodel.facets.FacetedMethodParameter;
+import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet;
import org.apache.isis.core.metamodel.facets.objectvalue.regex.RegExFacet;
import org.apache.isis.core.metamodel.facets.objectvalue.regex.TitleFacetFormattedByRegex;
import org.apache.isis.core.metamodel.facets.param.parameter.mandatory.MandatoryFacetForParameterAnnotation;
+import org.apache.isis.core.metamodel.facets.param.parameter.mandatory.MandatoryFacetInvertedByNullableAnnotationOnParameter;
import org.apache.isis.core.metamodel.facets.param.parameter.mandatory.MandatoryFacetInvertedByOptionalAnnotationOnParameter;
import org.apache.isis.core.metamodel.facets.param.parameter.maxlen.MaxLengthFacetForMaxLengthAnnotationOnParameter;
import org.apache.isis.core.metamodel.facets.param.parameter.maxlen.MaxLengthFacetForParameterAnnotation;
@@ -47,6 +51,7 @@ import org.apache.isis.core.metamodel.facets.param.parameter.regex.RegExFacetFor
import org.apache.isis.core.metamodel.facets.param.parameter.regex.RegExFacetFromRegExAnnotationOnParameter;
import org.apache.isis.core.metamodel.services.ServicesInjector;
import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorComposite;
+import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForConflictingOptionality;
import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForDeprecatedAnnotation;
public class ParameterAnnotationFacetFactory extends FacetFactoryAbstract implements MetaModelValidatorRefiner {
@@ -55,6 +60,7 @@ public class ParameterAnnotationFacetFactory extends FacetFactoryAbstract implem
private final MetaModelValidatorForDeprecatedAnnotation mustSatisfyValidator = new MetaModelValidatorForDeprecatedAnnotation(MustSatisfy.class);
private final MetaModelValidatorForDeprecatedAnnotation regexValidator = new MetaModelValidatorForDeprecatedAnnotation(RegEx.class);
private final MetaModelValidatorForDeprecatedAnnotation optionalValidator = new MetaModelValidatorForDeprecatedAnnotation(Optional.class);
+ private final MetaModelValidatorForConflictingOptionality conflictingOptionalityValidator = new MetaModelValidatorForConflictingOptionality();
public ParameterAnnotationFacetFactory() {
super(FeatureType.PARAMETERS_ONLY);
@@ -177,9 +183,21 @@ public class ParameterAnnotationFacetFactory extends FacetFactoryAbstract implem
final Class<?> parameterType = parameterTypes[paramNum];
if (parameterAnnotation instanceof Optional) {
final Optional annotation = (Optional) parameterAnnotation;
- final Facet facet = MandatoryFacetInvertedByOptionalAnnotationOnParameter.create(annotation, parameterType, holder);
- FacetUtil.addFacet(optionalValidator.flagIfPresent(facet, processParameterContext));
- return;
+ FacetUtil.addFacet(optionalValidator.flagIfPresent(
+ MandatoryFacetInvertedByOptionalAnnotationOnParameter.create(
+ annotation, parameterType, holder), processParameterContext));
+ }
+ }
+
+ for (final Annotation parameterAnnotation : parameterAnnotations) {
+ final Class<?> parameterType = parameterTypes[paramNum];
+ if (parameterAnnotation instanceof javax.annotation.Nullable) {
+ final Nullable annotation = (Nullable) parameterAnnotation;
+ final MandatoryFacet facet =
+ MandatoryFacetInvertedByNullableAnnotationOnParameter.create(annotation, parameterType, holder);
+ FacetUtil.addFacet(facet);
+ conflictingOptionalityValidator.flagIfConflict(
+ facet, "Conflicting @Nullable with other optionality annotation");
}
}
@@ -187,9 +205,11 @@ public class ParameterAnnotationFacetFactory extends FacetFactoryAbstract implem
if (parameterAnnotation instanceof Parameter) {
final Parameter parameter = (Parameter) parameterAnnotation;
final Class<?> parameterType = parameterTypes[paramNum];
- FacetUtil.addFacet(
- MandatoryFacetForParameterAnnotation.create(parameter, parameterType, holder));
- return;
+ final MandatoryFacet facet =
+ MandatoryFacetForParameterAnnotation.create(parameter, parameterType, holder);
+ FacetUtil.addFacet(facet);
+ conflictingOptionalityValidator.flagIfConflict(
+ facet, "Conflicting @Parameter#optionality with other optionality annotation");
}
}
}
@@ -200,9 +220,9 @@ public class ParameterAnnotationFacetFactory extends FacetFactoryAbstract implem
metaModelValidator.add(mustSatisfyValidator);
metaModelValidator.add(regexValidator);
metaModelValidator.add(optionalValidator);
+ metaModelValidator.add(conflictingOptionalityValidator);
}
-
@Override
public void setServicesInjector(final ServicesInjector servicesInjector) {
super.setServicesInjector(servicesInjector);
http://git-wip-us.apache.org/repos/asf/isis/blob/7dd5042d/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mandatory/MandatoryFacetInvertedByNullableAnnotationOnParameter.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mandatory/MandatoryFacetInvertedByNullableAnnotationOnParameter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mandatory/MandatoryFacetInvertedByNullableAnnotationOnParameter.java
new file mode 100644
index 0000000..a1dc49d
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/parameter/mandatory/MandatoryFacetInvertedByNullableAnnotationOnParameter.java
@@ -0,0 +1,53 @@
+/*
+ * 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.core.metamodel.facets.param.parameter.mandatory;
+
+import javax.annotation.Nullable;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.FacetedMethodParameter;
+import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet;
+import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFacetAbstract;
+
+/**
+ * Derived by presence of an {@link Nullable} annotation on parameter.
+ *
+ * <p>
+ * This implementation indicates that the {@link FacetHolder} is <i>not</i>
+ * mandatory, as per {@link #isInvertedSemantics()}.
+ */
+public class MandatoryFacetInvertedByNullableAnnotationOnParameter extends MandatoryFacetAbstract {
+
+ public static MandatoryFacet create(final Nullable annotation, final Class<?> parameterType, final FacetedMethodParameter holder) {
+ if(annotation == null) {
+ return null;
+ }
+ if(parameterType.isPrimitive()) {
+ return null;
+ }
+ return new MandatoryFacetInvertedByNullableAnnotationOnParameter(holder);
+ }
+
+ private MandatoryFacetInvertedByNullableAnnotationOnParameter(final FacetHolder holder) {
+ super(holder, Semantics.OPTIONAL);
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7dd5042d/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
index 76f1f32..82989f4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
@@ -21,6 +21,8 @@ package org.apache.isis.core.metamodel.facets.properties.property;
import java.lang.reflect.Method;
+import javax.annotation.Nullable;
+
import org.apache.isis.applib.annotation.Disabled;
import org.apache.isis.applib.annotation.Hidden;
import org.apache.isis.applib.annotation.Mandatory;
@@ -60,6 +62,7 @@ import org.apache.isis.core.metamodel.facets.properties.property.hidden.HiddenFa
import org.apache.isis.core.metamodel.facets.properties.property.hidden.HiddenFacetForPropertyAnnotation;
import org.apache.isis.core.metamodel.facets.properties.property.mandatory.MandatoryFacetForMandatoryAnnotationOnProperty;
import org.apache.isis.core.metamodel.facets.properties.property.mandatory.MandatoryFacetForPropertyAnnotation;
+import org.apache.isis.core.metamodel.facets.properties.property.mandatory.MandatoryFacetInvertedByNullableAnnotationOnProperty;
import org.apache.isis.core.metamodel.facets.properties.property.mandatory.MandatoryFacetInvertedByOptionalAnnotationOnProperty;
import org.apache.isis.core.metamodel.facets.properties.property.maxlength.MaxLengthFacetForMaxLengthAnnotationOnProperty;
import org.apache.isis.core.metamodel.facets.properties.property.maxlength.MaxLengthFacetForPropertyAnnotation;
@@ -87,6 +90,7 @@ import org.apache.isis.core.metamodel.facets.properties.update.clear.PropertyCle
import org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySetterFacet;
import org.apache.isis.core.metamodel.services.ServicesInjector;
import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorComposite;
+import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForConflictingOptionality;
import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForDeprecatedAnnotation;
import org.apache.isis.core.metamodel.util.EventUtil;
@@ -102,6 +106,8 @@ public class PropertyAnnotationFacetFactory extends FacetFactoryAbstract impleme
private final MetaModelValidatorForDeprecatedAnnotation maxLengthValidator = new MetaModelValidatorForDeprecatedAnnotation(MaxLength.class);
private final MetaModelValidatorForDeprecatedAnnotation mustSatisfyValidator = new MetaModelValidatorForDeprecatedAnnotation(MustSatisfy.class);
private final MetaModelValidatorForDeprecatedAnnotation notPersistedValidator = new MetaModelValidatorForDeprecatedAnnotation(NotPersisted.class);
+ private final MetaModelValidatorForConflictingOptionality conflictingOptionalityValidator = new MetaModelValidatorForConflictingOptionality();
+
public PropertyAnnotationFacetFactory() {
super(FeatureType.PROPERTIES_AND_ACTIONS);
@@ -386,23 +392,37 @@ public class PropertyAnnotationFacetFactory extends FacetFactoryAbstract impleme
final FacetHolder holder = processMethodContext.getFacetHolder();
- // check for deprecated @Optional first
+ // check for deprecated @Optional
final Optional optionalAnnotation = Annotations.getAnnotation(method, Optional.class);
- MandatoryFacet facet = optionalValidator.flagIfPresent(MandatoryFacetInvertedByOptionalAnnotationOnProperty.create(optionalAnnotation, method, holder), processMethodContext);
+ FacetUtil.addFacet(
+ optionalValidator.flagIfPresent(
+ MandatoryFacetInvertedByOptionalAnnotationOnProperty.create(optionalAnnotation, method, holder),
+ processMethodContext));
- // else check for deprecated @Mandatory first
+ // check for deprecated @Mandatory
final Mandatory mandatoryAnnotation = Annotations.getAnnotation(method, Mandatory.class);
- if(facet == null) {
- facet = mandatoryValidator.flagIfPresent(MandatoryFacetForMandatoryAnnotationOnProperty.create(mandatoryAnnotation, holder), processMethodContext);
- }
+ final MandatoryFacet facet =
+ mandatoryValidator.flagIfPresent(
+ MandatoryFacetForMandatoryAnnotationOnProperty.create(mandatoryAnnotation, holder),
+ processMethodContext);
+ FacetUtil.addFacet(facet);
+ conflictingOptionalityValidator.flagIfConflict(
+ facet, "Conflicting @Mandatory with other optionality annotation");
+
+ // else check for @Nullable
+ final Nullable nullableAnnotation = Annotations.getAnnotation(method, Nullable.class);
+ final MandatoryFacet facet2 =
+ MandatoryFacetInvertedByNullableAnnotationOnProperty.create(nullableAnnotation, method, holder);
+ FacetUtil.addFacet(facet2);
+ conflictingOptionalityValidator.flagIfConflict(
+ facet2, "Conflicting @Nullable with other optionality annotation");
// else search for @Property(optional=...)
final Property property = Annotations.getAnnotation(method, Property.class);
- if(facet == null) {
- facet = MandatoryFacetForPropertyAnnotation.create(property, method, holder);
- }
-
- FacetUtil.addFacet(facet);
+ final MandatoryFacet facet3 = MandatoryFacetForPropertyAnnotation.create(property, method, holder);
+ FacetUtil.addFacet(facet3);
+ conflictingOptionalityValidator.flagIfConflict(
+ facet3, "Conflicting Property#optionality with other optionality annotation");
}
void processRegEx(final ProcessMethodContext processMethodContext) {
@@ -444,6 +464,7 @@ public class PropertyAnnotationFacetFactory extends FacetFactoryAbstract impleme
metaModelValidator.add(maxLengthValidator);
metaModelValidator.add(mustSatisfyValidator);
metaModelValidator.add(notPersistedValidator);
+ metaModelValidator.add(conflictingOptionalityValidator);
}
// //////////////////////////////////////
http://git-wip-us.apache.org/repos/asf/isis/blob/7dd5042d/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/mandatory/MandatoryFacetInvertedByNullableAnnotationOnProperty.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/mandatory/MandatoryFacetInvertedByNullableAnnotationOnProperty.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/mandatory/MandatoryFacetInvertedByNullableAnnotationOnProperty.java
new file mode 100644
index 0000000..dbac2d5
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/mandatory/MandatoryFacetInvertedByNullableAnnotationOnProperty.java
@@ -0,0 +1,55 @@
+/*
+ * 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.core.metamodel.facets.properties.property.mandatory;
+
+import java.lang.reflect.Method;
+
+import javax.annotation.Nullable;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet;
+import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFacetAbstract;
+
+/**
+ * Derived by presence of an {@link Nullable} annotation.
+ *
+ * <p>
+ * This implementation indicates that the {@link FacetHolder} is <i>not</i>
+ * mandatory, as per {@link #isInvertedSemantics()}.
+ */
+public class MandatoryFacetInvertedByNullableAnnotationOnProperty extends MandatoryFacetAbstract {
+
+ public MandatoryFacetInvertedByNullableAnnotationOnProperty(final FacetHolder holder) {
+ super(holder, Semantics.OPTIONAL);
+ }
+
+ public static MandatoryFacet create(final Nullable annotation, Method method, final FacetHolder holder) {
+
+ if(annotation == null) {
+ return null;
+ }
+
+ final Class<?> returnType = method.getReturnType();
+ if (returnType.isPrimitive()) {
+ return null;
+ }
+ return new MandatoryFacetInvertedByNullableAnnotationOnProperty(holder);
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7dd5042d/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorAbstract.java
index bde6490..9e492c9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorAbstract.java
@@ -33,6 +33,4 @@ public abstract class MetaModelValidatorAbstract implements MetaModelValidator {
@Override
public void shutdown() {
}
-
-
}
http://git-wip-us.apache.org/repos/asf/isis/blob/7dd5042d/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForConflictingOptionality.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForConflictingOptionality.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForConflictingOptionality.java
new file mode 100644
index 0000000..514d1ea
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/validator/MetaModelValidatorForConflictingOptionality.java
@@ -0,0 +1,66 @@
+/*
+ * 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.core.metamodel.specloader.validator;
+
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
+import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet;
+import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFacetDefault;
+
+public class MetaModelValidatorForConflictingOptionality extends MetaModelValidatorAbstract {
+
+ private final ValidationFailures failures = new ValidationFailures();
+
+ public MetaModelValidatorForConflictingOptionality() {
+ }
+
+ @Override
+ public void validate(final ValidationFailures validationFailures) {
+ validationFailures.addAll(failures);
+ }
+
+ private Facet addFailure(final Facet facet, final String message) {
+ if(facet != null) {
+ failures.add(message + ": " + ((IdentifiedHolder) facet.getFacetHolder()).getIdentifier().toFullIdentityString());
+ }
+ return facet;
+ }
+
+ public Facet flagIfConflict(final MandatoryFacet facet, final String message) {
+ if(conflictingOptionality(facet)) {
+ addFailure(facet, message);
+ }
+ return facet;
+ }
+
+ private static boolean conflictingOptionality(final MandatoryFacet facet) {
+ if (facet == null) {
+ return false;
+ }
+ final MandatoryFacet underlyingFacet = (MandatoryFacet) facet.getUnderlyingFacet();
+ if(underlyingFacet instanceof MandatoryFacetDefault) {
+ return false;
+ }
+ final boolean conflicting =
+ underlyingFacet != null && facet.isInvertedSemantics() != underlyingFacet.isInvertedSemantics();
+ return conflicting;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7dd5042d/core/metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java
index 9cd9173..89332b0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java
@@ -113,7 +113,7 @@ public class MandatoryFromJdoColumnAnnotationFacetFactory extends FacetFactoryAb
// per JDO spec
return returnType != null && returnType.isPrimitive();
} else {
- return "false".equalsIgnoreCase(allowsNull.trim());
+ return !"true".equalsIgnoreCase(allowsNull.trim()); // if mis-spelt, then DN assumes is not-nullable
}
}