You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/11/12 13:16:58 UTC
[isis] branch master updated: ISIS-2882: BigDecimal scale fixes
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 32c15d1 ISIS-2882: BigDecimal scale fixes
32c15d1 is described below
commit 32c15d185401e62c9b6801e2ffb2b62688d909f2
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Nov 12 14:16:47 2021 +0100
ISIS-2882: BigDecimal scale fixes
- framework default scale for BigDecimal is 16 (that is, if there is no
scale explicitly specified)
- however, for JDO/JPA entities, when not specified the default scale is
0
---
.../applib/adapters/ValueSemanticsAbstract.java | 2 -
.../isis/commons/internal/base/_Optionals.java | 10 +++
...acetForPersistentBigDecimalWhenUnspecified.java | 73 ++++++++++++++++++++++
examples/demo/pre-flight.adoc | 1 +
...DecimalFromJdoColumnAnnotationFacetFactory.java | 17 ++++-
... => MaxFractionalDigitsFacetFromJdoColumn.java} | 6 +-
...malFromJdoColumnAnnotationFacetFactoryTest.java | 2 +-
...DecimalFromJpaColumnAnnotationFacetFactory.java | 17 ++++-
...ctionalDigitsFacetFromJpaColumnAnnotation.java} | 6 +-
9 files changed, 123 insertions(+), 11 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/isis/applib/adapters/ValueSemanticsAbstract.java b/api/applib/src/main/java/org/apache/isis/applib/adapters/ValueSemanticsAbstract.java
index 50606a8..e5f3b1a 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/adapters/ValueSemanticsAbstract.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/adapters/ValueSemanticsAbstract.java
@@ -130,9 +130,7 @@ implements
}
val format = getNumberFormat(context);
format.setParseBigDecimal(true);
- System.err.printf("before configure %d%n", format.getMaximumFractionDigits()); //FIXME[ISIS-2741] debug remove
configureDecimalFormat(context, format);
- System.err.printf("after configure %d%n", format.getMaximumFractionDigits()); //FIXME[ISIS-2741] debug remove
val position = new ParsePosition(0);
try {
diff --git a/commons/src/main/java/org/apache/isis/commons/internal/base/_Optionals.java b/commons/src/main/java/org/apache/isis/commons/internal/base/_Optionals.java
index 991d7b4..ec1e8b2 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/base/_Optionals.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/base/_Optionals.java
@@ -19,7 +19,9 @@
package org.apache.isis.commons.internal.base;
import java.util.Optional;
+import java.util.OptionalInt;
import java.util.function.Supplier;
+import java.util.function.ToIntFunction;
import lombok.experimental.UtilityClass;
@@ -42,4 +44,12 @@ public class _Optionals {
}
+ public <T> OptionalInt toInt(
+ final Optional<T> optional,
+ final ToIntFunction<? super T> mapper) {
+ return optional.isPresent()
+ ? OptionalInt.of(mapper.applyAsInt(optional.get()))
+ : OptionalInt.empty();
+ }
+
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/digits/MaxFractionalDigitsFacetForPersistentBigDecimalWhenUnspecified.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/digits/MaxFractionalDigitsFacetForPersistentBigDecimalWhenUnspecified.java
new file mode 100644
index 0000000..b25be82
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/digits/MaxFractionalDigitsFacetForPersistentBigDecimalWhenUnspecified.java
@@ -0,0 +1,73 @@
+/*
+ * 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.objectvalue.digits;
+
+import java.math.BigDecimal;
+import java.util.Optional;
+import java.util.OptionalInt;
+
+import org.apache.isis.core.config.beans.IsisBeanTypeRegistry;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.FacetFactory.ProcessMethodContext;
+
+import lombok.val;
+
+/**
+ * With {@link BigDecimal}, both JDO and JPA, if left unspecified,
+ * default their max-fractional digits to 0.
+ * (However, I could not find specific documents to support this claim.)
+ *
+ * @apiNote This facet should be applied in the absence of a corresponding {@code @Column} annotation,
+ * but only for properties of type {@link BigDecimal} that appear within a (persistable) entity.
+ * However, entities might extend abstract classes, where the framework - on type introspection -
+ * cannot distinguish entity from non-entity type.
+ * It is safe to assume that mixed-in properties are not to consider here.
+ */
+public class MaxFractionalDigitsFacetForPersistentBigDecimalWhenUnspecified
+extends MaxFractionalDigitsFacetAbstract {
+
+ public static Optional<MaxFractionalDigitsFacet> create(
+ final OptionalInt scaleIfAny,
+ final ProcessMethodContext processMethodContext,
+ final IsisBeanTypeRegistry beanTypeRegistry) {
+
+ val cls = processMethodContext.getCls();
+ val facetHolder = processMethodContext.getFacetHolder();
+
+ // only applies in a very specific context, see class java-doc
+ if(facetHolder.getFeatureType().isProperty()
+ || !processMethodContext.getMethod().getReturnType().equals(BigDecimal.class)
+ || !beanTypeRegistry.getEntityTypes().contains(cls)) {
+ return Optional.empty();
+ }
+
+ final int scale = scaleIfAny.orElse(-1);
+
+ return scale<0
+ ? Optional.of(new MaxFractionalDigitsFacetForPersistentBigDecimalWhenUnspecified(
+ facetHolder))
+ : Optional.empty();
+ }
+
+ private MaxFractionalDigitsFacetForPersistentBigDecimalWhenUnspecified(
+ final FacetHolder holder) {
+ super(0, holder);
+ }
+
+}
diff --git a/examples/demo/pre-flight.adoc b/examples/demo/pre-flight.adoc
index 42610bd..037c8b6 100644
--- a/examples/demo/pre-flight.adoc
+++ b/examples/demo/pre-flight.adoc
@@ -80,6 +80,7 @@ Returns scalar of: `demo.StatefulVmUsingJaxb`
* [ ] Test: click on the viewmodel's title, should render the very same thing
IMPORTANT: renders an empty object (JAXB serialization is not working as expected here)
+
* [ ] Test: open a Child, then return to previous page (browser back button)
[IMPORTANT]
diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactory.java b/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactory.java
index 29a21d9..b927b02 100644
--- a/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactory.java
+++ b/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactory.java
@@ -19,17 +19,21 @@
package org.apache.isis.persistence.jdo.metamodel.facets.prop.column;
import java.math.BigDecimal;
+import java.util.Optional;
import javax.inject.Inject;
import javax.jdo.annotations.Column;
import javax.jdo.annotations.IdentityType;
+import org.apache.isis.commons.internal.base._Optionals;
+import org.apache.isis.core.config.beans.IsisBeanTypeRegistry;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
import org.apache.isis.core.metamodel.facets.FacetedMethod;
import org.apache.isis.core.metamodel.facets.objectvalue.digits.MaxFractionalDigitsFacet;
+import org.apache.isis.core.metamodel.facets.objectvalue.digits.MaxFractionalDigitsFacetForPersistentBigDecimalWhenUnspecified;
import org.apache.isis.core.metamodel.facets.objectvalue.digits.MaxTotalDigitsFacet;
import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.core.metamodel.spec.feature.MixedIn;
@@ -44,9 +48,12 @@ public class BigDecimalFromJdoColumnAnnotationFacetFactory
extends FacetFactoryAbstract
implements MetaModelRefiner {
+ private Optional<IsisBeanTypeRegistry> beanTypeRegistryIfAny; // JUnit support (allowed to be empty)
+
@Inject
public BigDecimalFromJdoColumnAnnotationFacetFactory(final MetaModelContext mmc) {
super(mmc, FeatureType.PROPERTIES_ONLY);
+ beanTypeRegistryIfAny = mmc.getServiceRegistry().lookupService(IsisBeanTypeRegistry.class);
}
@Override
@@ -65,8 +72,16 @@ implements MetaModelRefiner {
.create(jdoColumnIfAny, holder));
addFacetIfPresent(
- MaxFractionDigitsFacetInferredFromJdoColumn
+ MaxFractionalDigitsFacetFromJdoColumn
.create(jdoColumnIfAny, holder));
+
+ // adds additional constraints if applicable
+ beanTypeRegistryIfAny.ifPresent(beanTypeRegistry->{
+ addFacetIfPresent(
+ MaxFractionalDigitsFacetForPersistentBigDecimalWhenUnspecified
+ .create(_Optionals.toInt(jdoColumnIfAny, Column::scale), processMethodContext, beanTypeRegistry));
+ });
+
}
@Override
diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/prop/column/MaxFractionDigitsFacetInferredFromJdoColumn.java b/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJdoColumn.java
similarity index 90%
rename from persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/prop/column/MaxFractionDigitsFacetInferredFromJdoColumn.java
rename to persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJdoColumn.java
index 87aa6a3..f87f784 100644
--- a/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/prop/column/MaxFractionDigitsFacetInferredFromJdoColumn.java
+++ b/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJdoColumn.java
@@ -26,7 +26,7 @@ import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facets.objectvalue.digits.MaxFractionalDigitsFacet;
import org.apache.isis.core.metamodel.facets.objectvalue.digits.MaxFractionalDigitsFacetAbstract;
-public class MaxFractionDigitsFacetInferredFromJdoColumn
+public class MaxFractionalDigitsFacetFromJdoColumn
extends MaxFractionalDigitsFacetAbstract {
public static Optional<MaxFractionalDigitsFacet> create(
@@ -36,12 +36,12 @@ extends MaxFractionalDigitsFacetAbstract {
return jdoColumnIfAny
.filter(jdoColumn->jdoColumn.scale()>=0)
.map(jdoColumn->{
- return new MaxFractionDigitsFacetInferredFromJdoColumn(
+ return new MaxFractionalDigitsFacetFromJdoColumn(
jdoColumn.scale(), holder);
});
}
- private MaxFractionDigitsFacetInferredFromJdoColumn(
+ private MaxFractionalDigitsFacetFromJdoColumn(
final int maxFractionalDigits, final FacetHolder holder) {
super(maxFractionalDigits, holder);
}
diff --git a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactoryTest.java b/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactoryTest.java
index 2006bfd..4b27ef7 100644
--- a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactoryTest.java
+++ b/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/prop/column/BigDecimalFromJdoColumnAnnotationFacetFactoryTest.java
@@ -114,7 +114,7 @@ extends AbstractFacetFactoryTest {
if(maxFractionalDigits>=0) {
final MaxFractionalDigitsFacet facet = facetedMethod.getFacet(MaxFractionalDigitsFacet.class);
assertNotNull(facet);
- assertTrue(facet instanceof MaxFractionDigitsFacetInferredFromJdoColumn);
+ assertTrue(facet instanceof MaxFractionalDigitsFacetFromJdoColumn);
assertThat(facet.getMaxFractionalDigits(), is(maxFractionalDigits));
} else {
assertNull(facetedMethod.getFacet(MaxFractionalDigitsFacet.class));
diff --git a/persistence/jpa/metamodel/src/main/java/org/apache/isis/persistence/jpa/metamodel/facets/prop/column/BigDecimalFromJpaColumnAnnotationFacetFactory.java b/persistence/jpa/metamodel/src/main/java/org/apache/isis/persistence/jpa/metamodel/facets/prop/column/BigDecimalFromJpaColumnAnnotationFacetFactory.java
index cf7d908..c2b0d3f 100644
--- a/persistence/jpa/metamodel/src/main/java/org/apache/isis/persistence/jpa/metamodel/facets/prop/column/BigDecimalFromJpaColumnAnnotationFacetFactory.java
+++ b/persistence/jpa/metamodel/src/main/java/org/apache/isis/persistence/jpa/metamodel/facets/prop/column/BigDecimalFromJpaColumnAnnotationFacetFactory.java
@@ -19,23 +19,30 @@
package org.apache.isis.persistence.jpa.metamodel.facets.prop.column;
import java.math.BigDecimal;
+import java.util.Optional;
import javax.inject.Inject;
import javax.persistence.Column;
+import org.apache.isis.commons.internal.base._Optionals;
+import org.apache.isis.core.config.beans.IsisBeanTypeRegistry;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
import org.apache.isis.core.metamodel.facets.FacetedMethod;
+import org.apache.isis.core.metamodel.facets.objectvalue.digits.MaxFractionalDigitsFacetForPersistentBigDecimalWhenUnspecified;
import lombok.val;
public class BigDecimalFromJpaColumnAnnotationFacetFactory
extends FacetFactoryAbstract {
+ private Optional<IsisBeanTypeRegistry> beanTypeRegistryIfAny; // JUnit support (allowed to be empty)
+
@Inject
public BigDecimalFromJpaColumnAnnotationFacetFactory(final MetaModelContext mmc) {
super(mmc, FeatureType.PROPERTIES_ONLY);
+ beanTypeRegistryIfAny = mmc.getServiceRegistry().lookupService(IsisBeanTypeRegistry.class);
}
@Override
@@ -54,8 +61,16 @@ extends FacetFactoryAbstract {
.create(jpaColumnIfAny, holder));
addFacetIfPresent(
- MaxFractionDigitsFacetFromJpaColumnAnnotation
+ MaxFractionalDigitsFacetFromJpaColumnAnnotation
.create(jpaColumnIfAny, holder));
+
+ // adds additional constraints if applicable
+ beanTypeRegistryIfAny.ifPresent(beanTypeRegistry->{
+ addFacetIfPresent(
+ MaxFractionalDigitsFacetForPersistentBigDecimalWhenUnspecified
+ .create(_Optionals.toInt(jpaColumnIfAny, Column::scale), processMethodContext, beanTypeRegistry));
+ });
+
}
}
diff --git a/persistence/jpa/metamodel/src/main/java/org/apache/isis/persistence/jpa/metamodel/facets/prop/column/MaxFractionDigitsFacetFromJpaColumnAnnotation.java b/persistence/jpa/metamodel/src/main/java/org/apache/isis/persistence/jpa/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJpaColumnAnnotation.java
similarity index 89%
rename from persistence/jpa/metamodel/src/main/java/org/apache/isis/persistence/jpa/metamodel/facets/prop/column/MaxFractionDigitsFacetFromJpaColumnAnnotation.java
rename to persistence/jpa/metamodel/src/main/java/org/apache/isis/persistence/jpa/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJpaColumnAnnotation.java
index 40d0f0c..c404f6f 100644
--- a/persistence/jpa/metamodel/src/main/java/org/apache/isis/persistence/jpa/metamodel/facets/prop/column/MaxFractionDigitsFacetFromJpaColumnAnnotation.java
+++ b/persistence/jpa/metamodel/src/main/java/org/apache/isis/persistence/jpa/metamodel/facets/prop/column/MaxFractionalDigitsFacetFromJpaColumnAnnotation.java
@@ -26,7 +26,7 @@ import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facets.objectvalue.digits.MaxFractionalDigitsFacet;
import org.apache.isis.core.metamodel.facets.objectvalue.digits.MaxFractionalDigitsFacetAbstract;
-public class MaxFractionDigitsFacetFromJpaColumnAnnotation
+public class MaxFractionalDigitsFacetFromJpaColumnAnnotation
extends MaxFractionalDigitsFacetAbstract {
public static Optional<MaxFractionalDigitsFacet> create(
@@ -36,12 +36,12 @@ extends MaxFractionalDigitsFacetAbstract {
return jpaColumnIfAny
.filter(jpaColumn->jpaColumn.scale()>=0)
.map(jdoColumn->{
- return new MaxFractionDigitsFacetFromJpaColumnAnnotation(
+ return new MaxFractionalDigitsFacetFromJpaColumnAnnotation(
jdoColumn.scale(), holder);
});
}
- private MaxFractionDigitsFacetFromJpaColumnAnnotation(
+ private MaxFractionalDigitsFacetFromJpaColumnAnnotation(
final int maxFractionalDigits, final FacetHolder holder) {
super(maxFractionalDigits, holder);
}