diff --git a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java index 8d0fe79af97..942c2c804b0 100644 --- a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java +++ b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java @@ -1444,6 +1444,25 @@ public static class ProgrammingModel { * have been indicated as deprecated will simply be ignored/excluded from the metamodel. */ private boolean ignoreDeprecated = false; + + + /** + * If set, then {@link Digits#fraction()}, the JDO @Column#scale and the JPA {@link Column#scale()} + * should be used for the MinFractionalFacet as well as the MaxFractionalFacet. + * + *

+ * What this means in practice is that a numeric values will be rendered to the same number of fractional digits, + * irrespective of whether they are whole numbers. For example, with a scale of 2, then + * "123.45" and also "123.00". + *

+ * + *

+ * If set to false, then these values would be rendered as "123.45", + * but for the whole integer instead just "123" (that is, the shortest textual + * representation). + *

+ */ + private boolean useScaleForMinFractionalFacet = true; } private final Introspector introspector = new Introspector(); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/objectvalue/digits/MaxTotalDigitsFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/objectvalue/digits/MaxTotalDigitsFacet.java index f1eab517d27..121c239f5d0 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/objectvalue/digits/MaxTotalDigitsFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/objectvalue/digits/MaxTotalDigitsFacet.java @@ -18,6 +18,7 @@ */ package org.apache.causeway.core.metamodel.facets.objectvalue.digits; +import javax.persistence.Column; import javax.validation.constraints.Digits; import org.apache.causeway.applib.annotation.ValueSemantics; @@ -33,6 +34,15 @@ *
  • 12345 has a total of 5 digits
  • *
  • 12345.0 has a total of 6 digits
  • * + * + *

    + * In JPA's {@link javax.persistence.Column}, this corresponds to {@link Column#precision()}. + * + *

    + * In JDO's @Column annotation, this corresponds to @Column#length. + * + *

    + * For {@link Digits}, corresponds to sum of {@link Digits#integer()} and {@link Digits#fraction()}. */ public interface MaxTotalDigitsFacet extends Facet { diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/value/semantics/MaxTotalDigitsFacetFromValueSemanticsAnnotation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/value/semantics/MaxTotalDigitsFacetFromValueSemanticsAnnotation.java index d3aef5dbd0f..f5c4f15cb82 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/value/semantics/MaxTotalDigitsFacetFromValueSemanticsAnnotation.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/value/semantics/MaxTotalDigitsFacetFromValueSemanticsAnnotation.java @@ -29,14 +29,11 @@ public class MaxTotalDigitsFacetFromValueSemanticsAnnotation extends MaxTotalDigitsFacetAbstract { public static Optional create( - final Optional digitsIfAny, + final Optional valueSemanticsIfAny, final FacetHolder holder) { - return digitsIfAny - .map(digits->{ - return new MaxTotalDigitsFacetFromValueSemanticsAnnotation( - digits.maxTotalDigits(), holder); - }); + return valueSemanticsIfAny + .map(digits-> new MaxTotalDigitsFacetFromValueSemanticsAnnotation(digits.maxTotalDigits(), holder)); } private MaxTotalDigitsFacetFromValueSemanticsAnnotation( diff --git a/persistence/commons/src/main/java/module-info.java b/persistence/commons/src/main/java/module-info.java index dc127a51dbb..981355e0188 100644 --- a/persistence/commons/src/main/java/module-info.java +++ b/persistence/commons/src/main/java/module-info.java @@ -19,6 +19,7 @@ module org.apache.causeway.persistence.commons { exports org.apache.causeway.persistence.jpa.integration.changetracking; exports org.apache.causeway.persistence.commons; + exports org.apache.causeway.persistence.commons.metamodel.facets.prop.column; requires java.annotation; requires java.desktop; diff --git a/persistence/commons/src/main/java/org/apache/causeway/persistence/commons/metamodel/facets/prop/column/BigDecimalFromXxxColumnAnnotationMetaModelRefinerUtil.java b/persistence/commons/src/main/java/org/apache/causeway/persistence/commons/metamodel/facets/prop/column/BigDecimalFromXxxColumnAnnotationMetaModelRefinerUtil.java new file mode 100644 index 00000000000..0e600923a7b --- /dev/null +++ b/persistence/commons/src/main/java/org/apache/causeway/persistence/commons/metamodel/facets/prop/column/BigDecimalFromXxxColumnAnnotationMetaModelRefinerUtil.java @@ -0,0 +1,41 @@ +package org.apache.causeway.persistence.commons.metamodel.facets.prop.column; + +import lombok.experimental.UtilityClass; + +import org.apache.causeway.core.metamodel.facets.objectvalue.digits.MaxFractionalDigitsFacet; +import org.apache.causeway.core.metamodel.facets.objectvalue.digits.MaxTotalDigitsFacet; +import org.apache.causeway.core.metamodel.spec.feature.ObjectAssociation; +import org.apache.causeway.core.metamodel.specloader.validator.ValidationFailure; + +@UtilityClass +public class BigDecimalFromXxxColumnAnnotationMetaModelRefinerUtil { + + public static void validateBigDecimalValueFacet(final ObjectAssociation association) { + + association.lookupFacet(MaxTotalDigitsFacet.class) + .map(MaxTotalDigitsFacet::getSharedFacetRankingElseFail) + .ifPresent(facetRanking->facetRanking + .visitTopRankPairsSemanticDiffering(MaxTotalDigitsFacet.class, (a, b)->{ + + ValidationFailure.raiseFormatted( + association, + "%s: inconsistent MaxTotalDigits semantics specified in %s and %s.", + association.getFeatureIdentifier().toString(), + a.getClass().getSimpleName(), + b.getClass().getSimpleName()); + })); + + association.lookupFacet(MaxFractionalDigitsFacet.class) + .map(MaxFractionalDigitsFacet::getSharedFacetRankingElseFail) + .ifPresent(facetRanking->facetRanking + .visitTopRankPairsSemanticDiffering(MaxFractionalDigitsFacet.class, (a, b)->{ + + ValidationFailure.raiseFormatted( + association, + "%s: inconsistent MaxFractionalDigits semantics specified in %s and %s.", + association.getFeatureIdentifier().toString(), + a.getClass().getSimpleName(), + b.getClass().getSimpleName()); + })); + } +} diff --git a/persistence/commons/src/main/java/org/apache/causeway/persistence/commons/metamodel/facets/prop/column/MandatoryFromXxxColumnAnnotationMetaModelRefinerUtil.java b/persistence/commons/src/main/java/org/apache/causeway/persistence/commons/metamodel/facets/prop/column/MandatoryFromXxxColumnAnnotationMetaModelRefinerUtil.java new file mode 100644 index 00000000000..312cd89fadf --- /dev/null +++ b/persistence/commons/src/main/java/org/apache/causeway/persistence/commons/metamodel/facets/prop/column/MandatoryFromXxxColumnAnnotationMetaModelRefinerUtil.java @@ -0,0 +1,28 @@ +package org.apache.causeway.persistence.commons.metamodel.facets.prop.column; + +import lombok.experimental.UtilityClass; + +import org.apache.causeway.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet; +import org.apache.causeway.core.metamodel.spec.feature.ObjectAssociation; +import org.apache.causeway.core.metamodel.specloader.validator.ValidationFailure; + +@UtilityClass +public class MandatoryFromXxxColumnAnnotationMetaModelRefinerUtil { + + public static void validateMandatoryFacet(final ObjectAssociation association) { + + association.lookupFacet(MandatoryFacet.class) + .map(MandatoryFacet::getSharedFacetRankingElseFail) + .ifPresent(facetRanking->facetRanking + .visitTopRankPairsSemanticDiffering(MandatoryFacet.class, (a, b)->{ + + ValidationFailure.raiseFormatted( + association, + "%s: inconsistent Mandatory/Optional semantics specified in %s and %s.", + association.getFeatureIdentifier().toString(), + a.getClass().getSimpleName(), + b.getClass().getSimpleName()); + })); + + } +} diff --git a/persistence/commons/src/main/java/org/apache/causeway/persistence/commons/metamodel/facets/prop/column/MaxLengthFromXxxColumnAnnotationMetaModelRefinerUtil.java b/persistence/commons/src/main/java/org/apache/causeway/persistence/commons/metamodel/facets/prop/column/MaxLengthFromXxxColumnAnnotationMetaModelRefinerUtil.java new file mode 100644 index 00000000000..dfcf3251acd --- /dev/null +++ b/persistence/commons/src/main/java/org/apache/causeway/persistence/commons/metamodel/facets/prop/column/MaxLengthFromXxxColumnAnnotationMetaModelRefinerUtil.java @@ -0,0 +1,25 @@ +package org.apache.causeway.persistence.commons.metamodel.facets.prop.column; + +import lombok.experimental.UtilityClass; + +import org.apache.causeway.core.metamodel.facets.objectvalue.maxlen.MaxLengthFacet; +import org.apache.causeway.core.metamodel.spec.feature.ObjectAssociation; +import org.apache.causeway.core.metamodel.specloader.validator.ValidationFailure; + +@UtilityClass +public class MaxLengthFromXxxColumnAnnotationMetaModelRefinerUtil { + public static void validateMaxLengthFacet(ObjectAssociation association) { + association.lookupFacet(MaxLengthFacet.class) + .map(MaxLengthFacet::getSharedFacetRankingElseFail) + .ifPresent(facetRanking->facetRanking + .visitTopRankPairsSemanticDiffering(MaxLengthFacet.class, (a, b)->{ + + ValidationFailure.raiseFormatted( + association, + "%s: inconsistent MaxLength semantics specified in %s and %s.", + association.getFeatureIdentifier().toString(), + a.getClass().getSimpleName(), + b.getClass().getSimpleName()); + })); + } +} diff --git a/persistence/jdo/metamodel/pom.xml b/persistence/jdo/metamodel/pom.xml index f3a45867180..bd37c2ac392 100644 --- a/persistence/jdo/metamodel/pom.xml +++ b/persistence/jdo/metamodel/pom.xml @@ -1,13 +1,13 @@ - @@ -37,26 +37,31 @@ org.apache.causeway.persistence causeway-persistence-jdo-applib - + org.apache.causeway.persistence causeway-persistence-jdo-provider - + + org.apache.causeway.persistence + causeway-persistence-commons + + + org.apache.causeway.core causeway-core-runtime - + org.apache.causeway.core causeway-core-internaltestsupport test - + \ No newline at end of file diff --git a/persistence/jdo/metamodel/src/main/java/module-info.java b/persistence/jdo/metamodel/src/main/java/module-info.java index c820846749f..f7748fa6d09 100644 --- a/persistence/jdo/metamodel/src/main/java/module-info.java +++ b/persistence/jdo/metamodel/src/main/java/module-info.java @@ -28,6 +28,7 @@ requires javax.jdo; requires org.apache.causeway.security.api; requires org.datanucleus.store.rdbms; + requires org.apache.causeway.persistence.commons; exports org.apache.causeway.persistence.jdo.metamodel; exports org.apache.causeway.persistence.jdo.metamodel.facets.object.persistencecapable; diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/JdoProgrammingModel.java b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/JdoProgrammingModel.java index 9ec479f00a9..483c62e633d 100644 --- a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/JdoProgrammingModel.java +++ b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/JdoProgrammingModel.java @@ -36,8 +36,8 @@ import org.apache.causeway.persistence.jdo.metamodel.facets.object.persistencecapable.JdoPersistenceCapableFacetFactory; import org.apache.causeway.persistence.jdo.metamodel.facets.object.query.JdoQueryAnnotationFacetFactory; import org.apache.causeway.persistence.jdo.metamodel.facets.object.version.JdoVersionAnnotationFacetFactory; -import org.apache.causeway.persistence.jdo.metamodel.facets.prop.column.BigDecimalFromColumnAnnotationFacetFactory; -import org.apache.causeway.persistence.jdo.metamodel.facets.prop.column.MandatoryFromColumnAnnotationFacetFactory; +import org.apache.causeway.persistence.jdo.metamodel.facets.prop.column.BigDecimalFromJdoColumnAnnotationFacetFactory; +import org.apache.causeway.persistence.jdo.metamodel.facets.prop.column.MandatoryFromJdoColumnAnnotationFacetFactory; import org.apache.causeway.persistence.jdo.metamodel.facets.prop.column.MaxLengthFromJdoColumnAnnotationFacetFactory; import org.apache.causeway.persistence.jdo.metamodel.facets.prop.notpersistent.JdoNotPersistentAnnotationFacetFactory; import org.apache.causeway.persistence.jdo.metamodel.facets.prop.primarykey.JdoPrimaryKeyAnnotationFacetFactory; @@ -82,12 +82,12 @@ public void refineProgrammingModel(final ProgrammingModel pm) { pm.addFactory(step2, new JdoQueryAnnotationFacetFactory(mmc, jdoFacetContext), Marker.JDO); - pm.addFactory(step2, new BigDecimalFromColumnAnnotationFacetFactory(mmc), Marker.JDO); + pm.addFactory(step2, new BigDecimalFromJdoColumnAnnotationFacetFactory(mmc), Marker.JDO); pm.addFactory(step2, new MaxLengthFromJdoColumnAnnotationFacetFactory(mmc), Marker.JDO); // must appear after JdoPrimaryKeyAnnotationFacetFactory (above) // and also MandatoryFacetOnPropertyMandatoryAnnotationFactory // and also PropertyAnnotationFactory - pm.addFactory(step2, new MandatoryFromColumnAnnotationFacetFactory(mmc, jdoFacetContext), Marker.JDO); + pm.addFactory(step2, new MandatoryFromJdoColumnAnnotationFacetFactory(mmc, jdoFacetContext), Marker.JDO); // -- validators diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromColumnAnnotationFacetFactory.java b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromColumnAnnotationFacetFactory.java deleted file mode 100644 index 158fcb9693d..00000000000 --- a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromColumnAnnotationFacetFactory.java +++ /dev/null @@ -1,131 +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.causeway.persistence.jdo.metamodel.facets.prop.column; - -import java.math.BigDecimal; - -import javax.inject.Inject; -import javax.jdo.annotations.IdentityType; - -import org.apache.causeway.core.metamodel.context.MetaModelContext; -import org.apache.causeway.core.metamodel.facetapi.FeatureType; -import org.apache.causeway.core.metamodel.facetapi.MetaModelRefiner; -import org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract; -import org.apache.causeway.core.metamodel.facets.FacetedMethod; -import org.apache.causeway.core.metamodel.facets.objectvalue.digits.MaxFractionalDigitsFacet; -import org.apache.causeway.core.metamodel.facets.objectvalue.digits.MaxTotalDigitsFacet; -import org.apache.causeway.core.metamodel.progmodel.ProgrammingModel; -import org.apache.causeway.core.metamodel.spec.feature.MixedIn; -import org.apache.causeway.core.metamodel.spec.feature.ObjectAssociation; -import org.apache.causeway.core.metamodel.specloader.validator.ValidationFailure; -import org.apache.causeway.persistence.jdo.provider.metamodel.facets.object.persistencecapable.JdoPersistenceCapableFacet; -import org.apache.causeway.persistence.jdo.provider.metamodel.facets.prop.notpersistent.JdoNotPersistentFacet; - -public class BigDecimalFromColumnAnnotationFacetFactory -extends FacetFactoryAbstract -implements MetaModelRefiner { - - @Inject - public BigDecimalFromColumnAnnotationFacetFactory(final MetaModelContext mmc) { - super(mmc, FeatureType.PROPERTIES_ONLY); - } - - @Override - public void process(final ProcessMethodContext processMethodContext) { - - if(BigDecimal.class != processMethodContext.getMethod().getReturnType()) { - return; - } - - final FacetedMethod holder = processMethodContext.getFacetHolder(); - - _ColumnUtil.processColumnAnnotations(processMethodContext, - jdoColumnIfAny->{ - addFacetIfPresent( - MaxTotalDigitsFacetFromJdoColumnAnnotation - .createJdo(jdoColumnIfAny, holder)); - - addFacetIfPresent( - MaxFractionalDigitsFacetFromJdoColumn - .createJdo(jdoColumnIfAny, holder)); - }, - jpaColumnIfAny->{ - addFacetIfPresent( - MaxTotalDigitsFacetFromJdoColumnAnnotation - .createJpa(jpaColumnIfAny, holder)); - - addFacetIfPresent( - MaxFractionalDigitsFacetFromJdoColumn - .createJpa(jpaColumnIfAny, holder)); - }); - - } - - @Override - public void refineProgrammingModel(final ProgrammingModel programmingModel) { - programmingModel.addValidatorSkipManagedBeans(spec->{ - - // only consider persistent entities - final JdoPersistenceCapableFacet pcFacet = spec.getFacet(JdoPersistenceCapableFacet.class); - if(pcFacet==null || pcFacet.getIdentityType() == IdentityType.NONDURABLE) { - return; - } - - spec.streamProperties(MixedIn.EXCLUDED) - // skip checks if annotated with JDO @NotPersistent - .filter(association->!association.containsNonFallbackFacet(JdoNotPersistentFacet.class)) - .forEach(association->{ - validateBigDecimalValueFacet(association); - }); - - }); - } - - private static void validateBigDecimalValueFacet(final ObjectAssociation association) { - - association.lookupFacet(MaxTotalDigitsFacet.class) - .map(MaxTotalDigitsFacet::getSharedFacetRankingElseFail) - .ifPresent(facetRanking->facetRanking - .visitTopRankPairsSemanticDiffering(MaxTotalDigitsFacet.class, (a, b)->{ - - ValidationFailure.raiseFormatted( - association, - "%s: inconsistent MaxTotalDigits semantics specified in %s and %s.", - association.getFeatureIdentifier().toString(), - a.getClass().getSimpleName(), - b.getClass().getSimpleName()); - })); - - association.lookupFacet(MaxFractionalDigitsFacet.class) - .map(MaxFractionalDigitsFacet::getSharedFacetRankingElseFail) - .ifPresent(facetRanking->facetRanking - .visitTopRankPairsSemanticDiffering(MaxFractionalDigitsFacet.class, (a, b)->{ - - ValidationFailure.raiseFormatted( - association, - "%s: inconsistent MaxFractionalDigits semantics specified in %s and %s.", - association.getFeatureIdentifier().toString(), - a.getClass().getSimpleName(), - b.getClass().getSimpleName()); - })); - - } - - -} diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactory.java b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactory.java new file mode 100644 index 00000000000..7b861766aa5 --- /dev/null +++ b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactory.java @@ -0,0 +1,89 @@ +/* + * 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.causeway.persistence.jdo.metamodel.facets.prop.column; + +import lombok.val; + +import java.math.BigDecimal; + +import javax.inject.Inject; +import javax.jdo.annotations.Column; +import javax.jdo.annotations.IdentityType; + +import org.apache.causeway.core.metamodel.context.MetaModelContext; +import org.apache.causeway.core.metamodel.facetapi.FeatureType; +import org.apache.causeway.core.metamodel.facetapi.MetaModelRefiner; +import org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract; +import org.apache.causeway.core.metamodel.facets.FacetedMethod; +import org.apache.causeway.core.metamodel.progmodel.ProgrammingModel; +import org.apache.causeway.core.metamodel.spec.feature.MixedIn; +import org.apache.causeway.persistence.commons.metamodel.facets.prop.column.BigDecimalFromXxxColumnAnnotationMetaModelRefinerUtil; +import org.apache.causeway.persistence.jdo.provider.metamodel.facets.object.persistencecapable.JdoPersistenceCapableFacet; +import org.apache.causeway.persistence.jdo.provider.metamodel.facets.prop.notpersistent.JdoNotPersistentFacet; + +public class BigDecimalFromJdoColumnAnnotationFacetFactory +extends FacetFactoryAbstract +implements MetaModelRefiner { + + @Inject + public BigDecimalFromJdoColumnAnnotationFacetFactory(final MetaModelContext mmc) { + super(mmc, FeatureType.PROPERTIES_ONLY); + } + + @Override + public void process(final ProcessMethodContext processMethodContext) { + + if(BigDecimal.class != processMethodContext.getMethod().getReturnType()) { + return; + } + + final FacetedMethod holder = processMethodContext.getFacetHolder(); + + val jdoColumnIfAny = processMethodContext.synthesizeOnMethod(Column.class); + + addFacetIfPresent( + MaxTotalDigitsFacetFromJdoColumnAnnotation + .create(jdoColumnIfAny, holder)); + + addFacetIfPresent( + MaxFractionalDigitsFacetFromJdoColumnAnnotation + .create(jdoColumnIfAny, holder)); + + } + + @Override + public void refineProgrammingModel(final ProgrammingModel programmingModel) { + programmingModel.addValidatorSkipManagedBeans(objectSpec->{ + + // only consider persistent entities + final JdoPersistenceCapableFacet pcFacet = objectSpec.getFacet(JdoPersistenceCapableFacet.class); + if(pcFacet==null || pcFacet.getIdentityType() == IdentityType.NONDURABLE) { + return; + } + + objectSpec + .streamProperties(MixedIn.EXCLUDED) + // skip checks if annotated with JDO @NotPersistent + .filter(association->!association.containsNonFallbackFacet(JdoNotPersistentFacet.class)) + .forEach(BigDecimalFromXxxColumnAnnotationMetaModelRefinerUtil::validateBigDecimalValueFacet); + + }); + } + +} diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFacetFromAbsenceOfColumnAnnotation.java b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFacetFromAbsenceOfJdoColumnAnnotation.java similarity index 91% rename from persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFacetFromAbsenceOfColumnAnnotation.java rename to persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFacetFromAbsenceOfJdoColumnAnnotation.java index 985adbec7f9..7c7c3244974 100644 --- a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFacetFromAbsenceOfColumnAnnotation.java +++ b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFacetFromAbsenceOfJdoColumnAnnotation.java @@ -24,10 +24,10 @@ /** * Inferred from absence of an @Column method. */ -public class MandatoryFacetFromAbsenceOfColumnAnnotation +public class MandatoryFacetFromAbsenceOfJdoColumnAnnotation extends MandatoryFacetAbstract { - public MandatoryFacetFromAbsenceOfColumnAnnotation( + public MandatoryFacetFromAbsenceOfJdoColumnAnnotation( final Semantics semantics, final FacetHolder holder, final Precedence precedence) { super(semantics, holder, precedence); } diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFacetFromColumnAnnotation.java b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFacetFromJdoColumnAnnotation.java similarity index 92% rename from persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFacetFromColumnAnnotation.java rename to persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFacetFromJdoColumnAnnotation.java index 5e159b19db6..fdb271f6ca9 100644 --- a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFacetFromColumnAnnotation.java +++ b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFacetFromJdoColumnAnnotation.java @@ -24,10 +24,10 @@ /** * Inferred from presence of an @Column annotation. */ -public class MandatoryFacetFromColumnAnnotation +public class MandatoryFacetFromJdoColumnAnnotation extends MandatoryFacetAbstract { - public MandatoryFacetFromColumnAnnotation( + public MandatoryFacetFromJdoColumnAnnotation( final Semantics semantics, final FacetHolder holder) { super(semantics, holder); } diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFromColumnAnnotationFacetFactory.java b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java similarity index 64% rename from persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFromColumnAnnotationFacetFactory.java rename to persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java index 8bbdd0b0e8e..127346607ae 100644 --- a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFromColumnAnnotationFacetFactory.java +++ b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java @@ -18,11 +18,16 @@ */ package org.apache.causeway.persistence.jdo.metamodel.facets.prop.column; +import lombok.val; + +import java.util.Optional; import java.util.stream.Stream; import javax.inject.Inject; +import javax.jdo.annotations.Column; import javax.jdo.annotations.IdentityType; +import org.apache.causeway.commons.internal.base._Strings; import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.facetapi.Facet.Precedence; import org.apache.causeway.core.metamodel.facetapi.FacetUtil; @@ -35,21 +40,21 @@ import org.apache.causeway.core.metamodel.progmodel.ProgrammingModel; import org.apache.causeway.core.metamodel.spec.feature.MixedIn; import org.apache.causeway.core.metamodel.spec.feature.ObjectAssociation; -import org.apache.causeway.core.metamodel.specloader.validator.ValidationFailure; +import org.apache.causeway.persistence.commons.metamodel.facets.prop.column.MandatoryFromXxxColumnAnnotationMetaModelRefinerUtil; import org.apache.causeway.persistence.jdo.metamodel.facets.prop.primarykey.MandatoryFacetFromJdoPrimaryKeyAnnotation; import org.apache.causeway.persistence.jdo.provider.entities.JdoFacetContext; import org.apache.causeway.persistence.jdo.provider.metamodel.facets.object.persistencecapable.JdoPersistenceCapableFacet; import org.apache.causeway.persistence.jdo.provider.metamodel.facets.prop.notpersistent.JdoNotPersistentFacet; -public class MandatoryFromColumnAnnotationFacetFactory +public class MandatoryFromJdoColumnAnnotationFacetFactory extends FacetFactoryAbstract implements MetaModelRefiner { private final JdoFacetContext jdoFacetContext; @Inject - public MandatoryFromColumnAnnotationFacetFactory( + public MandatoryFromJdoColumnAnnotationFacetFactory( final MetaModelContext mmc, final JdoFacetContext jdoFacetContext) { super(mmc, FeatureType.PROPERTIES_ONLY); @@ -82,23 +87,46 @@ public void process(final ProcessMethodContext processMethodContext) { } } - _ColumnUtil.inferSemantics(processMethodContext, - semanticsWhileColumnPresent->{ - FacetUtil.addFacet( - new MandatoryFacetFromColumnAnnotation(semanticsWhileColumnPresent, holder)); - }, - semanticsWhileColumnAbsent->{ - FacetUtil.addFacet( - new MandatoryFacetFromAbsenceOfColumnAnnotation( - semanticsWhileColumnAbsent, - holder, - semanticsWhileColumnAbsent.isRequired() - ? Precedence.DEFAULT - : Precedence.INFERRED)); - }); + val jdoColumnIfAny = processMethodContext.synthesizeOnMethod(javax.jdo.annotations.Column.class); + MandatoryFacet.Semantics semantics = inferSemantics(processMethodContext, jdoColumnIfAny); + if(jdoColumnIfAny.isPresent()) { + FacetUtil.addFacet( + new MandatoryFacetFromJdoColumnAnnotation(semantics, holder)); + } else { + FacetUtil.addFacet( + new MandatoryFacetFromAbsenceOfJdoColumnAnnotation( + semantics, + holder, + semantics.isRequired() + ? Precedence.DEFAULT + : Precedence.INFERRED)); + } + + } + + static MandatoryFacet.Semantics inferSemantics( + final ProcessMethodContext processMethodContext, + final Optional columnIfAny) { + + final String allowsNull = columnIfAny.isPresent() + ? columnIfAny.get().allowsNull() + : null; + + if(_Strings.isNotEmpty(allowsNull)) { + // if miss-spelled, then DN assumes is not-nullable + return MandatoryFacet.Semantics.required(!"true".equalsIgnoreCase(allowsNull.trim())); + } + + final Class returnType = processMethodContext.getMethod().getReturnType(); + // per JDO spec + return returnType != null + && returnType.isPrimitive() + ? MandatoryFacet.Semantics.REQUIRED + : MandatoryFacet.Semantics.OPTIONAL; } + @Override public void refineProgrammingModel(final ProgrammingModel programmingModel) { programmingModel.addValidatorSkipManagedBeans(objectSpec->{ @@ -108,33 +136,13 @@ public void refineProgrammingModel(final ProgrammingModel programmingModel) { return; } - final Stream associations = objectSpec - .streamAssociations(MixedIn.EXCLUDED) - .filter(ObjectAssociation.Predicates.PROPERTIES); - - associations - // skip checks if annotated with JDO @NotPersistent - .filter(association->!association.containsNonFallbackFacet(JdoNotPersistentFacet.class)) - .forEach(association->validateMandatoryFacet(association)); + objectSpec + .streamProperties(MixedIn.EXCLUDED) + // skip checks if annotated with JDO @NotPersistent + .filter(association->!association.containsNonFallbackFacet(JdoNotPersistentFacet.class)) + .forEach(MandatoryFromXxxColumnAnnotationMetaModelRefinerUtil::validateMandatoryFacet); }); } - private static void validateMandatoryFacet(final ObjectAssociation association) { - - association.lookupFacet(MandatoryFacet.class) - .map(MandatoryFacet::getSharedFacetRankingElseFail) - .ifPresent(facetRanking->facetRanking - .visitTopRankPairsSemanticDiffering(MandatoryFacet.class, (a, b)->{ - - ValidationFailure.raiseFormatted( - association, - "%s: inconsistent Mandatory/Optional semantics specified in %s and %s.", - association.getFeatureIdentifier().toString(), - a.getClass().getSimpleName(), - b.getClass().getSimpleName()); - })); - - } - } diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJdoColumn.java b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJdoColumnAnnotation.java similarity index 69% rename from persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJdoColumn.java rename to persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJdoColumnAnnotation.java index b150bef8cd7..a20e3eb613e 100644 --- a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJdoColumn.java +++ b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJdoColumnAnnotation.java @@ -26,37 +26,24 @@ import org.apache.causeway.core.metamodel.facets.objectvalue.digits.MaxFractionalDigitsFacet; import org.apache.causeway.core.metamodel.facets.objectvalue.digits.MaxFractionalDigitsFacetAbstract; -public class MaxFractionalDigitsFacetFromJdoColumn +public class MaxFractionalDigitsFacetFromJdoColumnAnnotation extends MaxFractionalDigitsFacetAbstract { - public static Optional createJdo( + public static Optional create( final Optional jdoColumnIfAny, final FacetHolder holder) { return jdoColumnIfAny .filter(jdoColumn->jdoColumn.scale()>=0) .map(jdoColumn->{ - return new MaxFractionalDigitsFacetFromJdoColumn( + return new MaxFractionalDigitsFacetFromJdoColumnAnnotation( jdoColumn.scale(), holder); }); } - public static Optional createJpa( - final Optional jdoColumnIfAny, - final FacetHolder holder) { - - return jdoColumnIfAny - .filter(jdoColumn->jdoColumn.scale()>=0) - .map(jdoColumn->{ - return new MaxFractionalDigitsFacetFromJdoColumn( - jdoColumn.scale(), holder); - }); + private MaxFractionalDigitsFacetFromJdoColumnAnnotation( + final int scale, final FacetHolder holder) { + super(scale, holder); } - private MaxFractionalDigitsFacetFromJdoColumn( - final int maxFractionalDigits, final FacetHolder holder) { - super(maxFractionalDigits, holder); - } - - } diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxLengthFacetFromJdoColumnAnnotation.java b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxLengthFacetFromJdoColumnAnnotation.java index 4ca01d5fbb0..65cbfa9c7d9 100644 --- a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxLengthFacetFromJdoColumnAnnotation.java +++ b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxLengthFacetFromJdoColumnAnnotation.java @@ -29,24 +29,15 @@ public class MaxLengthFacetFromJdoColumnAnnotation extends MaxLengthFacetAbstract { - public static Optional createJdo( - final Optional jdoColumnIfAny, + public static Optional create( + final Optional columnIfAny, final FacetHolder holder) { - return jdoColumnIfAny - .map(jdoColumn-> - new MaxLengthFacetFromJdoColumnAnnotation( - jdoColumn.length(), holder)); - } - - public static Optional createJpa( - final Optional jpaColumnIfAny, - final FacetHolder holder) { - - return jpaColumnIfAny - .map(jdoColumn-> - new MaxLengthFacetFromJdoColumnAnnotation( - jdoColumn.length(), holder)); + return columnIfAny + .filter(column -> column.length() > 0) + .map(column-> + new MaxLengthFacetFromJdoColumnAnnotation( + column.length(), holder)); } private MaxLengthFacetFromJdoColumnAnnotation( diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxLengthFromJdoColumnAnnotationFacetFactory.java b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxLengthFromJdoColumnAnnotationFacetFactory.java index 6d330e0c199..4785fc487f8 100644 --- a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxLengthFromJdoColumnAnnotationFacetFactory.java +++ b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxLengthFromJdoColumnAnnotationFacetFactory.java @@ -21,6 +21,7 @@ import java.util.stream.Stream; import javax.inject.Inject; +import javax.jdo.annotations.Column; import javax.jdo.annotations.IdentityType; import org.apache.causeway.core.metamodel.context.MetaModelContext; @@ -28,11 +29,10 @@ import org.apache.causeway.core.metamodel.facetapi.FeatureType; import org.apache.causeway.core.metamodel.facetapi.MetaModelRefiner; import org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract; -import org.apache.causeway.core.metamodel.facets.objectvalue.maxlen.MaxLengthFacet; import org.apache.causeway.core.metamodel.progmodel.ProgrammingModel; import org.apache.causeway.core.metamodel.spec.feature.MixedIn; import org.apache.causeway.core.metamodel.spec.feature.ObjectAssociation; -import org.apache.causeway.core.metamodel.specloader.validator.ValidationFailure; +import org.apache.causeway.persistence.commons.metamodel.facets.prop.column.MaxLengthFromXxxColumnAnnotationMetaModelRefinerUtil; import org.apache.causeway.persistence.jdo.provider.entities.JdoFacetContext; import org.apache.causeway.persistence.jdo.provider.metamodel.facets.object.persistencecapable.JdoPersistenceCapableFacet; import org.apache.causeway.persistence.jdo.provider.metamodel.facets.prop.notpersistent.JdoNotPersistentFacet; @@ -64,52 +64,27 @@ public void process(final ProcessMethodContext processMethodContext) { val facetHolder = processMethodContext.getFacetHolder(); - _ColumnUtil.processColumnAnnotations(processMethodContext, - jdoColumnIfAny->{ - FacetUtil.addFacetIfPresent( - MaxTotalDigitsFacetFromJdoColumnAnnotation - .createJdo(jdoColumnIfAny, facetHolder)); - }, - jpaColumnIfAny->{ - FacetUtil.addFacetIfPresent( - MaxTotalDigitsFacetFromJdoColumnAnnotation - .createJpa(jpaColumnIfAny, facetHolder)); - }); + val jdoColumnIfAny = processMethodContext.synthesizeOnMethod(Column.class); + FacetUtil.addFacetIfPresent( + MaxLengthFacetFromJdoColumnAnnotation + .create(jdoColumnIfAny, facetHolder)); } @Override public void refineProgrammingModel(final ProgrammingModel programmingModel) { programmingModel.addValidatorSkipManagedBeans(objectSpec->{ + final JdoPersistenceCapableFacet pcFacet = objectSpec.getFacet(JdoPersistenceCapableFacet.class); if(pcFacet==null || pcFacet.getIdentityType() == IdentityType.NONDURABLE) { return; } - final Stream associations = objectSpec - .streamAssociations(MixedIn.EXCLUDED) - .filter(ObjectAssociation.Predicates.PROPERTIES); - - associations.forEach(association->{ - // skip checks if annotated with JDO @NotPersistent - if(association.containsNonFallbackFacet(JdoNotPersistentFacet.class)) { - return; - } - - association.lookupFacet(MaxLengthFacet.class) - .map(MaxLengthFacet::getSharedFacetRankingElseFail) - .ifPresent(facetRanking->facetRanking - .visitTopRankPairsSemanticDiffering(MaxLengthFacet.class, (a, b)->{ - - ValidationFailure.raiseFormatted( - association, - "%s: inconsistent MaxLength semantics specified in %s and %s.", - association.getFeatureIdentifier().toString(), - a.getClass().getSimpleName(), - b.getClass().getSimpleName()); - })); - - }); + objectSpec + .streamProperties(MixedIn.EXCLUDED) + // skip checks if annotated with JDO @NotPersistent + .filter(association->!association.containsNonFallbackFacet(JdoNotPersistentFacet.class)) + .forEach(MaxLengthFromXxxColumnAnnotationMetaModelRefinerUtil::validateMaxLengthFacet); }); } diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxTotalDigitsFacetFromJdoColumnAnnotation.java b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxTotalDigitsFacetFromJdoColumnAnnotation.java index 11b7edc5ba1..0098aebd607 100644 --- a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxTotalDigitsFacetFromJdoColumnAnnotation.java +++ b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MaxTotalDigitsFacetFromJdoColumnAnnotation.java @@ -29,31 +29,19 @@ public class MaxTotalDigitsFacetFromJdoColumnAnnotation extends MaxTotalDigitsFacetAbstract { - public static Optional createJdo( - final Optional jdoColumnIfAny, + public static Optional create( + final Optional columnIfAny, final FacetHolder holder) { - return jdoColumnIfAny - .filter(jdoColumn->jdoColumn.length()>=0) - .map(jdoColumn-> - new MaxTotalDigitsFacetFromJdoColumnAnnotation( - jdoColumn.length(), holder)); - } - - public static Optional createJpa( - final Optional jpaColumnIfAny, - final FacetHolder holder) { - - return jpaColumnIfAny - .filter(jpaColumn->jpaColumn.length()>=0) - .map(jpaColumn-> - new MaxTotalDigitsFacetFromJdoColumnAnnotation( - jpaColumn.length(), holder)); + return columnIfAny + .filter(column->column.length()>=0) + .map(column-> + new MaxTotalDigitsFacetFromJdoColumnAnnotation(column.length(), holder)); } private MaxTotalDigitsFacetFromJdoColumnAnnotation( - final int maxTotalDigits, final FacetHolder holder) { - super(maxTotalDigits, holder); + final int length, final FacetHolder holder) { + super(length, holder); } } diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/_ColumnUtil.java b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/_ColumnUtil.java deleted file mode 100644 index 89b95503a51..00000000000 --- a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/_ColumnUtil.java +++ /dev/null @@ -1,93 +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.causeway.persistence.jdo.metamodel.facets.prop.column; - -import java.util.Optional; -import java.util.function.Consumer; - -import javax.jdo.annotations.Column; - -import org.apache.causeway.commons.internal.base._Strings; -import org.apache.causeway.core.metamodel.facets.FacetFactory.ProcessMethodContext; -import org.apache.causeway.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet.Semantics; - -import lombok.val; -import lombok.experimental.UtilityClass; - -@UtilityClass -class _ColumnUtil { - - void processColumnAnnotations(final ProcessMethodContext processMethodContext, - final Consumer> onJdoColumn, - final Consumer> onJpaColumn) { - - val jdoColumnIfAny = processMethodContext.synthesizeOnMethod(javax.jdo.annotations.Column.class); - if(jdoColumnIfAny.isPresent()) { - onJdoColumn.accept(jdoColumnIfAny); - } else { - val jpaColumnIfAny = processMethodContext.synthesizeOnMethod(javax.persistence.Column.class); - if(jpaColumnIfAny.isPresent()) { - onJpaColumn.accept(jpaColumnIfAny); - } - } - - } - - void inferSemantics(final ProcessMethodContext processMethodContext, - final Consumer onColumnPresent, - final Consumer onColumnNotPresent) { - val jdoColumnIfAny = processMethodContext.synthesizeOnMethod(javax.jdo.annotations.Column.class); - if(jdoColumnIfAny.isPresent()) { - onColumnPresent.accept(inferSemantics(processMethodContext, jdoColumnIfAny)); - return; - } - val jpaColumnIfAny = processMethodContext.synthesizeOnMethod(javax.persistence.Column.class); - if(jpaColumnIfAny.isPresent()) { - onColumnPresent.accept(Semantics.required(!jpaColumnIfAny.get().nullable())); - return; - } - onColumnNotPresent.accept(inferSemantics(processMethodContext, Optional.empty())); - } - - // -- HELPER - - private Semantics inferSemantics( - final ProcessMethodContext processMethodContext, - final Optional columnIfAny) { - - final String allowsNull = columnIfAny.isPresent() - ? columnIfAny.get().allowsNull() - : null; - - if(_Strings.isNotEmpty(allowsNull)) { - // if miss-spelled, then DN assumes is not-nullable - return Semantics.required(!"true".equalsIgnoreCase(allowsNull.trim())); - } - - final Class returnType = processMethodContext.getMethod().getReturnType(); - // per JDO spec - return returnType != null - && returnType.isPrimitive() - ? Semantics.REQUIRED - : Semantics.OPTIONAL; - - } - -} diff --git a/persistence/jdo/metamodel/src/test/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactoryTest.java b/persistence/jdo/metamodel/src/test/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactoryTest.java index 15e135aa5be..bc28d1ab064 100644 --- a/persistence/jdo/metamodel/src/test/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactoryTest.java +++ b/persistence/jdo/metamodel/src/test/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactoryTest.java @@ -38,14 +38,14 @@ class BigDecimalFromJdoColumnAnnotationFacetFactoryTest extends AbstractFacetFactoryTest { - private BigDecimalFromColumnAnnotationFacetFactory facetFactory; + private BigDecimalFromJdoColumnAnnotationFacetFactory facetFactory; @Override protected void setUp() throws Exception { super.setUp(); val mmc = MetaModelContext_forTesting.buildDefault(); - facetFactory = new BigDecimalFromColumnAnnotationFacetFactory(mmc); + facetFactory = new BigDecimalFromJdoColumnAnnotationFacetFactory(mmc); } @Override @@ -115,7 +115,7 @@ private void assertBigDecimalSemantics( if(maxFractionalDigits>=0) { final MaxFractionalDigitsFacet facet = facetedMethod.getFacet(MaxFractionalDigitsFacet.class); assertNotNull(facet); - assertTrue(facet instanceof MaxFractionalDigitsFacetFromJdoColumn); + assertTrue(facet instanceof MaxFractionalDigitsFacetFromJdoColumnAnnotation); assertThat(facet.getMaxFractionalDigits(), is(maxFractionalDigits)); } else { assertNull(facetedMethod.getFacet(MaxFractionalDigitsFacet.class)); diff --git a/persistence/jdo/metamodel/src/test/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactoryTest.java b/persistence/jdo/metamodel/src/test/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactoryTest.java index 4d9d3199ddb..440bf3f65ce 100644 --- a/persistence/jdo/metamodel/src/test/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactoryTest.java +++ b/persistence/jdo/metamodel/src/test/java/org/apache/causeway/persistence/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactoryTest.java @@ -34,14 +34,14 @@ class MandatoryFromJdoColumnAnnotationFacetFactoryTest extends AbstractFacetFactoryTest { - private MandatoryFromColumnAnnotationFacetFactory facetFactory; + private MandatoryFromJdoColumnAnnotationFacetFactory facetFactory; private Class cls; @Override protected void setUp() throws Exception { super.setUp(); - facetFactory = new MandatoryFromColumnAnnotationFacetFactory(metaModelContext, jdoFacetContext); + facetFactory = new MandatoryFromJdoColumnAnnotationFacetFactory(metaModelContext, jdoFacetContext); cls = SimpleObjectWithColumnAllowsNullAnnotations.class; } @@ -67,7 +67,7 @@ public void testPrimitiveWithNoAnnotation_isMandatory() throws Exception { final MandatoryFacet facet = facetedMethod.getFacet(MandatoryFacet.class); assertNotNull(facet); - assertTrue(facet instanceof MandatoryFacetFromAbsenceOfColumnAnnotation); + assertTrue(facet instanceof MandatoryFacetFromAbsenceOfJdoColumnAnnotation); assertThat(facet.getSemantics().isOptional(), is(false)); } @@ -78,7 +78,7 @@ public void testPrimitiveWithNoAllowsNull_isMandatory() throws Exception { final MandatoryFacet facet = facetedMethod.getFacet(MandatoryFacet.class); assertNotNull(facet); - assertTrue(facet instanceof MandatoryFacetFromColumnAnnotation); + assertTrue(facet instanceof MandatoryFacetFromJdoColumnAnnotation); assertThat(facet.getSemantics().isOptional(), is(false)); } @@ -89,7 +89,7 @@ public void testPrimitiveWithAllowsNullFalse() throws Exception { final MandatoryFacet facet = facetedMethod.getFacet(MandatoryFacet.class); assertNotNull(facet); - assertTrue(facet instanceof MandatoryFacetFromColumnAnnotation); + assertTrue(facet instanceof MandatoryFacetFromJdoColumnAnnotation); assertThat(facet.getSemantics().isOptional(), is(false)); } @@ -100,7 +100,7 @@ public void testPrimitiveWithAllowsNullTrue() throws Exception { final MandatoryFacet facet = facetedMethod.getFacet(MandatoryFacet.class); assertNotNull(facet); - assertTrue(facet instanceof MandatoryFacetFromColumnAnnotation); + assertTrue(facet instanceof MandatoryFacetFromJdoColumnAnnotation); assertThat(facet.getSemantics().isOptional(), is(true)); } @@ -111,7 +111,7 @@ public void testReferenceWithNoAnnotation_isOptional() throws Exception { final MandatoryFacet facet = facetedMethod.getFacet(MandatoryFacet.class); assertNotNull(facet); - assertTrue(facet instanceof MandatoryFacetFromAbsenceOfColumnAnnotation); + assertTrue(facet instanceof MandatoryFacetFromAbsenceOfJdoColumnAnnotation); assertThat(facet.getSemantics().isOptional(), is(true)); } @@ -122,7 +122,7 @@ public void testReferenceWithNoAllowsNull_isOptional() throws Exception { final MandatoryFacet facet = facetedMethod.getFacet(MandatoryFacet.class); assertNotNull(facet); - assertTrue(facet instanceof MandatoryFacetFromColumnAnnotation); + assertTrue(facet instanceof MandatoryFacetFromJdoColumnAnnotation); assertThat(facet.getSemantics().isOptional(), is(true)); } @@ -133,7 +133,7 @@ public void testReferenceWithAllowsNullFalse() throws Exception { final MandatoryFacet facet = facetedMethod.getFacet(MandatoryFacet.class); assertNotNull(facet); - assertTrue(facet instanceof MandatoryFacetFromColumnAnnotation); + assertTrue(facet instanceof MandatoryFacetFromJdoColumnAnnotation); assertThat(facet.getSemantics().isOptional(), is(false)); } @@ -144,7 +144,7 @@ public void testReferenceWithAllowsNullTrue() throws Exception { final MandatoryFacet facet = facetedMethod.getFacet(MandatoryFacet.class); assertNotNull(facet); - assertTrue(facet instanceof MandatoryFacetFromColumnAnnotation); + assertTrue(facet instanceof MandatoryFacetFromJdoColumnAnnotation); assertThat(facet.getSemantics().isOptional(), is(true)); } diff --git a/persistence/jpa/metamodel/pom.xml b/persistence/jpa/metamodel/pom.xml index e97a9d63d12..9f782b171ce 100644 --- a/persistence/jpa/metamodel/pom.xml +++ b/persistence/jpa/metamodel/pom.xml @@ -1,13 +1,13 @@ - @@ -37,14 +37,19 @@ org.apache.causeway.persistence causeway-persistence-jpa-applib - - + + + org.apache.causeway.persistence + causeway-persistence-commons + + + org.apache.causeway.core causeway-core-runtime - + org.apache.causeway.core causeway-core-internaltestsupport diff --git a/persistence/jpa/metamodel/src/main/java/module-info.java b/persistence/jpa/metamodel/src/main/java/module-info.java index ad5d858e20f..950bebd7150 100644 --- a/persistence/jpa/metamodel/src/main/java/module-info.java +++ b/persistence/jpa/metamodel/src/main/java/module-info.java @@ -32,4 +32,5 @@ requires org.apache.causeway.core.runtime; requires org.apache.causeway.persistence.jpa.applib; requires spring.context; + requires org.apache.causeway.persistence.commons; } \ No newline at end of file diff --git a/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/JpaProgrammingModel.java b/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/JpaProgrammingModel.java index 138b6f190a0..a01d47ce502 100644 --- a/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/JpaProgrammingModel.java +++ b/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/JpaProgrammingModel.java @@ -18,6 +18,8 @@ */ package org.apache.causeway.persistence.jpa.metamodel; +import org.apache.causeway.persistence.jpa.metamodel.facets.prop.column.MaxLengthFromJpaColumnAnnotationFacetFactory; + import org.springframework.stereotype.Component; import org.apache.causeway.core.metamodel.facetapi.MetaModelRefiner; @@ -45,6 +47,7 @@ public void refineProgrammingModel(final ProgrammingModel pm) { pm.addFactory(step, new JpaTransientAnnotationFacetFactory(mmc), Marker.JPA); pm.addFactory(step, new MandatoryFromJpaColumnAnnotationFacetFactory(mmc), Marker.JPA); pm.addFactory(step, new BigDecimalFromJpaColumnAnnotationFacetFactory(mmc), Marker.JPA); + pm.addFactory(step, new MaxLengthFromJpaColumnAnnotationFacetFactory(mmc), Marker.JPA); } diff --git a/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/BigDecimalFromJpaColumnAnnotationFacetFactory.java b/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/BigDecimalFromJpaColumnAnnotationFacetFactory.java index 583b32b06e9..bed0b2a3118 100644 --- a/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/BigDecimalFromJpaColumnAnnotationFacetFactory.java +++ b/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/BigDecimalFromJpaColumnAnnotationFacetFactory.java @@ -25,13 +25,18 @@ import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.facetapi.FeatureType; +import org.apache.causeway.core.metamodel.facetapi.MetaModelRefiner; import org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract; import org.apache.causeway.core.metamodel.facets.FacetedMethod; +import org.apache.causeway.core.metamodel.progmodel.ProgrammingModel; +import org.apache.causeway.core.metamodel.spec.feature.MixedIn; +import org.apache.causeway.persistence.commons.metamodel.facets.prop.column.BigDecimalFromXxxColumnAnnotationMetaModelRefinerUtil; import lombok.val; public class BigDecimalFromJpaColumnAnnotationFacetFactory -extends FacetFactoryAbstract { +extends FacetFactoryAbstract +implements MetaModelRefiner { @Inject public BigDecimalFromJpaColumnAnnotationFacetFactory(final MetaModelContext mmc) { @@ -59,4 +64,15 @@ public void process(final ProcessMethodContext processMethodContext) { } + @Override + public void refineProgrammingModel(final ProgrammingModel programmingModel) { + programmingModel.addValidatorSkipManagedBeans(objectSpec->{ + + objectSpec + .streamProperties(MixedIn.EXCLUDED) + .forEach(BigDecimalFromXxxColumnAnnotationMetaModelRefinerUtil::validateBigDecimalValueFacet); + + }); + } + } diff --git a/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MandatoryFromJpaColumnAnnotationFacetFactory.java b/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MandatoryFromJpaColumnAnnotationFacetFactory.java index e24ef5951a8..0040f88d9a3 100644 --- a/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MandatoryFromJpaColumnAnnotationFacetFactory.java +++ b/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MandatoryFromJpaColumnAnnotationFacetFactory.java @@ -19,6 +19,7 @@ package org.apache.causeway.persistence.jpa.metamodel.facets.prop.column; import java.util.Optional; +import java.util.stream.Stream; import javax.inject.Inject; import javax.persistence.Column; @@ -27,13 +28,19 @@ import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.facetapi.FacetUtil; import org.apache.causeway.core.metamodel.facetapi.FeatureType; +import org.apache.causeway.core.metamodel.facetapi.MetaModelRefiner; import org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract; import org.apache.causeway.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet.Semantics; +import org.apache.causeway.core.metamodel.progmodel.ProgrammingModel; +import org.apache.causeway.core.metamodel.spec.feature.MixedIn; +import org.apache.causeway.core.metamodel.spec.feature.ObjectAssociation; +import org.apache.causeway.persistence.commons.metamodel.facets.prop.column.MandatoryFromXxxColumnAnnotationMetaModelRefinerUtil; import lombok.val; public class MandatoryFromJpaColumnAnnotationFacetFactory -extends FacetFactoryAbstract { +extends FacetFactoryAbstract +implements MetaModelRefiner { @Inject public MandatoryFromJpaColumnAnnotationFacetFactory(final MetaModelContext mmc) { @@ -43,8 +50,6 @@ public MandatoryFromJpaColumnAnnotationFacetFactory(final MetaModelContext mmc) @Override public void process(final ProcessMethodContext processMethodContext) { - //val cls = processMethodContext.getCls(); - final Optional nullable1 = processMethodContext.synthesizeOnMethod(JoinColumn.class) .map(JoinColumn::nullable); @@ -64,5 +69,15 @@ public void process(final ProcessMethodContext processMethodContext) { new MandatoryFacetFromJpaColumnAnnotation(semantics, facetHolder)); } + @Override + public void refineProgrammingModel(final ProgrammingModel programmingModel) { + programmingModel.addValidatorSkipManagedBeans(objectSpec->{ + + objectSpec + .streamProperties(MixedIn.EXCLUDED) + .forEach(MandatoryFromXxxColumnAnnotationMetaModelRefinerUtil::validateMandatoryFacet); + + }); + } } diff --git a/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJpaColumnAnnotation.java b/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJpaColumnAnnotation.java index 84b3677ced3..98d8b4572ee 100644 --- a/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJpaColumnAnnotation.java +++ b/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJpaColumnAnnotation.java @@ -30,20 +30,17 @@ public class MaxFractionalDigitsFacetFromJpaColumnAnnotation extends MaxFractionalDigitsFacetAbstract { public static Optional create( - final Optional jpaColumnIfAny, + final Optional columnIfAny, final FacetHolder holder) { - return jpaColumnIfAny - .filter(jpaColumn->jpaColumn.scale()>=0) - .map(jdoColumn->{ - return new MaxFractionalDigitsFacetFromJpaColumnAnnotation( - jdoColumn.scale(), holder); - }); + return columnIfAny + .filter(column->column.scale()>=0) + .map(column-> new MaxFractionalDigitsFacetFromJpaColumnAnnotation(column.scale(), holder)); } private MaxFractionalDigitsFacetFromJpaColumnAnnotation( - final int maxFractionalDigits, final FacetHolder holder) { - super(maxFractionalDigits, holder); + final int scale, final FacetHolder holder) { + super(scale, holder); } } diff --git a/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MaxLengthFacetFromJpaColumnAnnotation.java b/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MaxLengthFacetFromJpaColumnAnnotation.java new file mode 100644 index 00000000000..19aaf5270ff --- /dev/null +++ b/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MaxLengthFacetFromJpaColumnAnnotation.java @@ -0,0 +1,49 @@ +/* + * 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.causeway.persistence.jpa.metamodel.facets.prop.column; + +import java.util.Optional; + +import javax.persistence.Column; + +import org.apache.causeway.core.metamodel.facetapi.FacetHolder; +import org.apache.causeway.core.metamodel.facets.objectvalue.maxlen.MaxLengthFacet; +import org.apache.causeway.core.metamodel.facets.objectvalue.maxlen.MaxLengthFacetAbstract; + +public class MaxLengthFacetFromJpaColumnAnnotation +extends MaxLengthFacetAbstract { + + public static Optional create( + final Optional columnIfAny, + final FacetHolder holder) { + + return columnIfAny + .filter(column -> column.length() > 0) + .map(column-> + new MaxLengthFacetFromJpaColumnAnnotation( + column.length(), holder)); + } + + private MaxLengthFacetFromJpaColumnAnnotation( + final int maxLength, final FacetHolder holder) { + super(maxLength, holder); + } + + +} diff --git a/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MaxLengthFromJpaColumnAnnotationFacetFactory.java b/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MaxLengthFromJpaColumnAnnotationFacetFactory.java new file mode 100644 index 00000000000..3efa4ca5c65 --- /dev/null +++ b/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MaxLengthFromJpaColumnAnnotationFacetFactory.java @@ -0,0 +1,74 @@ +/* + * 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.causeway.persistence.jpa.metamodel.facets.prop.column; + +import javax.persistence.Column; + +import org.apache.causeway.core.metamodel.context.MetaModelContext; +import org.apache.causeway.core.metamodel.facetapi.FacetUtil; +import org.apache.causeway.core.metamodel.facetapi.FeatureType; +import org.apache.causeway.core.metamodel.facetapi.MetaModelRefiner; +import org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract; +import org.apache.causeway.core.metamodel.progmodel.ProgrammingModel; +import org.apache.causeway.core.metamodel.spec.feature.MixedIn; +import org.apache.causeway.core.metamodel.spec.feature.ObjectAssociation; +import org.apache.causeway.persistence.commons.metamodel.facets.prop.column.MaxLengthFromXxxColumnAnnotationMetaModelRefinerUtil; + +import lombok.val; + +import java.util.stream.Stream; + +public class MaxLengthFromJpaColumnAnnotationFacetFactory +extends FacetFactoryAbstract +implements MetaModelRefiner { + + public MaxLengthFromJpaColumnAnnotationFacetFactory(final MetaModelContext mmc) { + super(mmc, FeatureType.PROPERTIES_ONLY); + } + + @Override + public void process(final ProcessMethodContext processMethodContext) { + + // only applies to JDO entities; ignore any view models + final Class cls = processMethodContext.getCls(); + + if(String.class != processMethodContext.getMethod().getReturnType()) { + return; + } + + val facetHolder = processMethodContext.getFacetHolder(); + + val jdoColumnIfAny = processMethodContext.synthesizeOnMethod(Column.class); + + FacetUtil.addFacetIfPresent( + MaxLengthFacetFromJpaColumnAnnotation + .create(jdoColumnIfAny, facetHolder)); + } + + @Override + public void refineProgrammingModel(final ProgrammingModel programmingModel) { + programmingModel.addValidatorSkipManagedBeans(objectSpec->{ + + objectSpec + .streamProperties(MixedIn.EXCLUDED) + .forEach(MaxLengthFromXxxColumnAnnotationMetaModelRefinerUtil::validateMaxLengthFacet); + }); + } + +} diff --git a/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MaxTotalDigitsFacetFromJpaColumnAnnotation.java b/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MaxTotalDigitsFacetFromJpaColumnAnnotation.java index a72a8ad85b9..97ba9e2d846 100644 --- a/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MaxTotalDigitsFacetFromJpaColumnAnnotation.java +++ b/persistence/jpa/metamodel/src/main/java/org/apache/causeway/persistence/jpa/metamodel/facets/prop/column/MaxTotalDigitsFacetFromJpaColumnAnnotation.java @@ -30,19 +30,19 @@ public class MaxTotalDigitsFacetFromJpaColumnAnnotation extends MaxTotalDigitsFacetAbstract { public static Optional create( - final Optional jpaColumnIfAny, + final Optional columnIfAny, final FacetHolder holder) { - return jpaColumnIfAny - .filter(jpaColumn->jpaColumn.length()>=0) - .map(jdoColumn-> - new MaxTotalDigitsFacetFromJpaColumnAnnotation( - jdoColumn.length(), holder)); + return columnIfAny + .filter(column->column.precision()>0) + .map(column-> + new MaxTotalDigitsFacetFromJpaColumnAnnotation( + column.precision(), holder)); } private MaxTotalDigitsFacetFromJpaColumnAnnotation( - final int maxTotalDigits, final FacetHolder holder) { - super(maxTotalDigits, holder); + final int precision, final FacetHolder holder) { + super(precision, holder); } diff --git a/regressiontests/stable-viewers-jdo/src/test/java/org/apache/causeway/testdomain/viewers/jdo/wkt/InteractionTestJdoWkt.java b/regressiontests/stable-viewers-jdo/src/test/java/org/apache/causeway/testdomain/viewers/jdo/wkt/InteractionTestJdoWkt.java index f5bb8f9989b..54c5b59a326 100644 --- a/regressiontests/stable-viewers-jdo/src/test/java/org/apache/causeway/testdomain/viewers/jdo/wkt/InteractionTestJdoWkt.java +++ b/regressiontests/stable-viewers-jdo/src/test/java/org/apache/causeway/testdomain/viewers/jdo/wkt/InteractionTestJdoWkt.java @@ -20,6 +20,9 @@ import javax.inject.Inject; +import org.apache.causeway.core.metamodel.object.ManagedObject; +import org.apache.causeway.testdomain.jpa.entities.JpaBook; + import org.apache.wicket.ajax.AjaxEventBehavior; import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton; import org.apache.wicket.markup.html.basic.Label; @@ -55,6 +58,8 @@ import static org.apache.causeway.testdomain.conf.Configuration_usingWicket.EntityPageTester.OPEN_SAMPLE_ACTION_TITLE; import static org.apache.causeway.testdomain.conf.Configuration_usingWicket.EntityPageTester.STANDALONE_COLLECTION_LABEL; +import static org.junit.jupiter.api.Assertions.assertTrue; + import lombok.val; @SpringBootTest( @@ -109,11 +114,12 @@ void load_viewmodel_with_referenced_entities_directly() { run(()->{ wktTester.startEntityPage(pageParameters); + //XXX activate for test troubleshooting + // wktTester.dumpComponentTree(comp->true); + wktTester.assertHeaderBrandText("Smoke Tests"); wktTester.assertPageTitle("JdoInventoryJaxbVm; Bookstore; 3 products"); - //wktTester.dumpComponentTree(comp->true); - wktTester.assertFavoriteBookIs(BookDto.sample()); }); @@ -187,6 +193,8 @@ void load_viewmodel_with_referenced_entities_via_action() { } + private ManagedObject bookAdapter; + @Test void loadBookPage_Dune_then_change_Isbn() { val pageParameters = call(()->{ @@ -196,11 +204,17 @@ void loadBookPage_Dune_then_change_Isbn() { .findFirst() .orElseThrow(); + System.err.printf("--- adapt %n"); + bookAdapter = super.objectManager.adapt(jdoBook); + return wktTester.createPageParameters(jdoBook); }); //System.err.printf("pageParameters %s%n", pageParameters); + assertEquals(ManagedObject.Specialization.ENTITY, bookAdapter.getSpecialization()); + assertTrue(bookAdapter.isBookmarkMemoized(), "bookAdapter should be bookmarked"); + // open Dune page run(()->{ wktTester.startEntityPage(pageParameters); @@ -225,12 +239,27 @@ void loadBookPage_Dune_then_change_Isbn() { val form = wktTester.newFormTester(bookIsbn.editInlinePromptForm()); form.setValue(bookIsbn.scalarField(), "ISBN-XXXX"); form.submit(); + + val jpaBook = (JdoBook)bookAdapter.getPojo(); + assertEquals("ISBN-A", jpaBook.getIsbn()); }); // simulate click on form OK button -> expected to trigger the framework's property change execution run(()->{ wktTester.assertComponent(bookIsbn.editInlinePromptFormOk(), IndicatingAjaxButton.class); + + wktTester.dumpComponentTree(comp->true); + System.out.println( + wktTester.getLastResponseAsString() + ); + wktTester.executeAjaxEvent(bookIsbn.editInlinePromptFormOk(), "click"); + + System.err.printf("bookAdapter state %s%n", bookAdapter.getEntityState()); + + System.err.printf("--- verify %n"); + val jpaBook = (JdoBook)bookAdapter.getPojo(); + assertEquals("ISBN-XXXX", jpaBook.getIsbn()); }); // ... should yield a new Title containing 'Dune [ISBN-XXXX]'