This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch v3
in repository https://gitbox.apache.org/repos/asf/causeway.git
The following commit(s) were added to refs/heads/v3 by this push:
new c57ed24418e CAUSEWAY-2297: ditch PropertyMemento (instead make
one2one-assoc serializable)
c57ed24418e is described below
commit c57ed24418e98e1d57a69ca45d1511f62262fca1
Author: Andi Huber <[email protected]>
AuthorDate: Sat Nov 23 19:05:36 2024 +0100
CAUSEWAY-2297: ditch PropertyMemento (instead make one2one-assoc
serializable)
---
.../spec/feature/OneToOneAssociation.java | 8 ---
.../spec/feature/memento/PropertyMemento.java | 81 ----------------------
.../specimpl/OneToOneAssociationDefault.java | 31 ++++++++-
.../specimpl/OneToOneAssociationMixedIn.java | 1 +
.../domainmodel/DomainModelTest_serialization.java | 23 ++++++
.../viewer/wicket/model/models/UiObjectWkt.java | 23 +++---
6 files changed, 65 insertions(+), 102 deletions(-)
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/OneToOneAssociation.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/OneToOneAssociation.java
index 74a3b8b3e01..d34335dab85 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/OneToOneAssociation.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/OneToOneAssociation.java
@@ -22,7 +22,6 @@ import org.apache.causeway.core.metamodel.consent.Consent;
import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
import
org.apache.causeway.core.metamodel.facets.propcoll.memserexcl.SnapshotExcludeFacet;
import org.apache.causeway.core.metamodel.object.ManagedObject;
-import org.apache.causeway.core.metamodel.spec.feature.memento.PropertyMemento;
/**
* Provides reflective access to a field on a domain object that is used to
@@ -74,11 +73,4 @@ extends
return prefix + ownerObjectType + "-" + memberId;
}
- /**
- * Returns a serializable representation of this property.
- */
- default PropertyMemento getMemento() {
- return PropertyMemento.forProperty(this);
- }
-
}
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/memento/PropertyMemento.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/memento/PropertyMemento.java
deleted file mode 100644
index ed7a713addd..00000000000
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/memento/PropertyMemento.java
+++ /dev/null
@@ -1,81 +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.core.metamodel.spec.feature.memento;
-
-import java.io.Serializable;
-import java.util.function.Supplier;
-
-import org.apache.causeway.applib.Identifier;
-import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.causeway.core.metamodel.specloader.SpecificationLoader;
-
-import lombok.AccessLevel;
-import lombok.AllArgsConstructor;
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import lombok.NonNull;
-import lombok.Synchronized;
-
-/**
- * {@link Serializable} representation of an {@link OneToOneAssociation}
- *
- * @implNote thread-safe memoization
- *
- * @since 2.0 {index}
- */
-@EqualsAndHashCode
-@AllArgsConstructor(access = AccessLevel.PROTECTED)
-public class PropertyMemento implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- @EqualsAndHashCode.Include
- @Getter private final @NonNull Identifier identifier;
-
- // -- FACTORY
-
- public static PropertyMemento forProperty(final @NonNull
OneToOneAssociation property) {
- return new PropertyMemento(
- property.getFeatureIdentifier(),
- property);
- }
-
- // -- LOAD/UNMARSHAL
-
- @EqualsAndHashCode.Exclude
- private transient OneToOneAssociation property;
-
- @Synchronized
- public OneToOneAssociation getProperty(final @NonNull
Supplier<SpecificationLoader> specLoader) {
- if (property == null) {
- property = specLoader.get()
-
.specForLogicalTypeElseFail(getIdentifier().getLogicalType())
-
.getPropertyElseFail(getIdentifier().getMemberLogicalName());
- }
- return property;
- }
-
- // -- OBJECT CONTRACT
-
- @Override
- public String toString() {
- return getIdentifier().getLogicalTypeName() + "#" +
getIdentifier().getMemberLogicalName();
- }
-
-}
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
index f0e7b6c3ccb..b25cb3fb118 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
@@ -18,6 +18,10 @@
*/
package org.apache.causeway.core.metamodel.specloader.specimpl;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+
import org.apache.causeway.applib.Identifier;
import org.apache.causeway.applib.annotation.Property;
import org.apache.causeway.applib.annotation.PropertyLayout;
@@ -29,6 +33,7 @@ import
org.apache.causeway.commons.internal.exceptions._Exceptions;
import org.apache.causeway.core.metamodel.commons.ToString;
import org.apache.causeway.core.metamodel.consent.Consent;
import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
+import org.apache.causeway.core.metamodel.context.MetaModelContext;
import org.apache.causeway.core.metamodel.facetapi.FeatureType;
import org.apache.causeway.core.metamodel.facets.FacetedMethod;
import
org.apache.causeway.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet;
@@ -58,7 +63,8 @@ import lombok.Getter;
public class OneToOneAssociationDefault
extends ObjectAssociationAbstract
-implements OneToOneAssociation {
+implements OneToOneAssociation, Serializable {
+ private static final long serialVersionUID = 1L;
// -- FACTORY
@@ -342,4 +348,27 @@ implements OneToOneAssociation {
|| methodFacade.synthesize(PropertyLayout.class).isPresent();
}
+ // -- SERIALIZATION PROXY
+
+ protected final Object writeReplace() {
+ return new SerializationProxy(this);
+ }
+
+ protected final void readObject(final ObjectInputStream stream) throws
InvalidObjectException {
+ throw new InvalidObjectException("Proxy required");
+ }
+
+ protected record SerializationProxy(Identifier identifier) implements
Serializable {
+ SerializationProxy(final OneToOneAssociationDefault property) {
+ this(property.getFeatureIdentifier());
+ }
+ private Object readResolve() {
+ return MetaModelContext.instanceElseFail()
+ .getSpecificationLoader()
+ .specForLogicalTypeElseFail(identifier.getLogicalType())
+ .getPropertyElseFail(
+ identifier.getMemberLogicalName());
+ }
+ }
+
}
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
index b1b30ca7c9e..3ab7e884a85 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
@@ -43,6 +43,7 @@ import lombok.Getter;
public class OneToOneAssociationMixedIn
extends OneToOneAssociationDefault
implements MixedInMember {
+ private static final long serialVersionUID = 1L;
// -- FACTORIES
diff --git
a/regressiontests/domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/DomainModelTest_serialization.java
b/regressiontests/domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/DomainModelTest_serialization.java
index 10d589633e1..9c9188b685e 100644
---
a/regressiontests/domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/DomainModelTest_serialization.java
+++
b/regressiontests/domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/DomainModelTest_serialization.java
@@ -34,6 +34,8 @@ import
org.apache.causeway.core.metamodel.specloader.specimpl.ObjectActionDefaul
import
org.apache.causeway.core.metamodel.specloader.specimpl.ObjectActionMixedIn;
import
org.apache.causeway.core.metamodel.specloader.specimpl.OneToManyAssociationDefault;
import
org.apache.causeway.core.metamodel.specloader.specimpl.OneToManyAssociationMixedIn;
+import
org.apache.causeway.core.metamodel.specloader.specimpl.OneToOneAssociationDefault;
+import
org.apache.causeway.core.metamodel.specloader.specimpl.OneToOneAssociationMixedIn;
import org.apache.causeway.testdomain.conf.Configuration_headless;
import
org.apache.causeway.testdomain.model.good.Configuration_usingValidDomain;
import org.apache.causeway.testdomain.model.good.ProperMemberSupport;
@@ -58,6 +60,8 @@ class DomainModelTest_serialization extends
CausewayIntegrationTestAbstract {
@Inject private SpecificationLoader specificationLoader;
+ // -- ACT
+
@Test
void objectActionDefault_shouldBe_Serializable() {
var holderSpec =
specificationLoader.specForTypeElseFail(ProperMemberSupport.class);
@@ -73,6 +77,25 @@ class DomainModelTest_serialization extends
CausewayIntegrationTestAbstract {
_SerializationTester.assertEqualsOnRoundtrip(act);
}
+ // -- PROP
+
+ @Test
+ void oneToOneAssociationDefault_shouldBe_Serializable() {
+ var holderSpec =
specificationLoader.specForTypeElseFail(ProperMemberSupport.class);
+ var prop = (OneToOneAssociationDefault)
holderSpec.getPropertyElseFail("myProp");
+ assertEquals(OneToOneAssociationDefault.class, prop.getClass());
+ _SerializationTester.assertEqualsOnRoundtrip(prop);
+ }
+ @Test
+ void oneToOneAssociationMixedIn_shouldBe_Serializable() {
+ var holderSpec =
specificationLoader.specForTypeElseFail(ProperMemberSupport.class);
+ var prop = (OneToOneAssociationMixedIn)
holderSpec.getPropertyElseFail("property1");
+ assertEquals(OneToOneAssociationMixedIn.class, prop.getClass());
+ _SerializationTester.assertEqualsOnRoundtrip(prop);
+ }
+
+ // -- COLL
+
@Test
void oneToManyAssociationDefault_shouldBe_Serializable() {
var holderSpec =
specificationLoader.specForTypeElseFail(ProperMemberSupport.class);
diff --git
a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/UiObjectWkt.java
b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/UiObjectWkt.java
index d29b2605081..f039baafcea 100644
---
a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/UiObjectWkt.java
+++
b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/UiObjectWkt.java
@@ -18,6 +18,7 @@
*/
package org.apache.causeway.viewer.wicket.model.models;
+import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;
@@ -28,6 +29,7 @@ import org.apache.wicket.request.resource.ResourceReference;
import org.springframework.lang.Nullable;
+import org.apache.causeway.applib.Identifier;
import
org.apache.causeway.applib.exceptions.unrecoverable.ObjectNotFoundException;
import org.apache.causeway.applib.fa.FontAwesomeLayers;
import org.apache.causeway.applib.services.bookmark.Bookmark;
@@ -35,7 +37,6 @@ import org.apache.causeway.applib.services.hint.HintStore;
import org.apache.causeway.commons.functional.Either;
import org.apache.causeway.commons.internal.assertions._Assert;
import org.apache.causeway.commons.internal.base._NullSafe;
-import org.apache.causeway.commons.internal.collections._Maps;
import org.apache.causeway.core.metamodel.commons.ViewOrEditMode;
import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
import org.apache.causeway.core.metamodel.facets.object.icon.ObjectIcon;
@@ -43,7 +44,6 @@ import
org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.core.metamodel.object.ManagedObjects;
import org.apache.causeway.core.metamodel.spec.feature.MixedIn;
import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.causeway.core.metamodel.spec.feature.memento.PropertyMemento;
import org.apache.causeway.viewer.commons.model.hints.RenderingHint;
import org.apache.causeway.viewer.commons.model.object.UiObject;
import org.apache.causeway.viewer.wicket.model.hints.UiHintContainer;
@@ -200,10 +200,10 @@ implements
// -- PROPERTY MODELS (CHILDREN)
- private transient Map<PropertyMemento, ScalarPropertyModel>
propertyScalarModels;
- private Map<PropertyMemento, ScalarPropertyModel> propertyScalarModels() {
+ private transient Map<Identifier, ScalarPropertyModel>
propertyScalarModels;
+ private Map<Identifier, ScalarPropertyModel> propertyScalarModels() {
if(propertyScalarModels==null) {
- propertyScalarModels = _Maps.<PropertyMemento,
ScalarPropertyModel>newHashMap();
+ propertyScalarModels = new HashMap<>();
}
return propertyScalarModels;
}
@@ -231,29 +231,29 @@ implements
bookmarkedObjectModel.getBookmark().getIdentifier());
}
- var pm = property.getMemento();
+ var propIdentifier = property.getFeatureIdentifier();
var propertyScalarModels = propertyScalarModels();
- final ScalarModel existingScalarModel = propertyScalarModels.get(pm);
+ final ScalarModel existingScalarModel =
propertyScalarModels.get(propIdentifier);
if (existingScalarModel != null) {
return existingScalarModel;
}
var propertyInteractionModel = new PropertyInteractionWkt(
bookmarkedObjectModel,
- pm.getIdentifier().getMemberLogicalName(),
+ propIdentifier.getMemberLogicalName(),
renderingHint.asWhere());
final long modelsAdded =
propertyInteractionModel.streamPropertyUiModels()
.map(uiModel->ScalarPropertyModel.wrap(uiModel, viewOrEdit,
renderingHint))
.peek(scalarModel->log.debug("adding: {}", scalarModel))
- .filter(scalarModel->propertyScalarModels.put(pm, scalarModel)==null)
+ .filter(scalarModel->propertyScalarModels.put(propIdentifier,
scalarModel)==null)
.count(); // consume the stream
// future extensions might allow to add multiple UI models per single
property model (typed tuple support)
_Assert.assertEquals(1L, modelsAdded, ()->
String.format("unexpected number of propertyScalarModels added
%d", modelsAdded));
- return propertyScalarModels.get(pm);
+ return propertyScalarModels.get(propIdentifier);
}
@Override
@@ -303,8 +303,7 @@ implements
public boolean isContextAdapter(final ManagedObject other) {
return contextBookmarkIfAny==null
? false
- : Objects.equals(contextBookmarkIfAny,
other.getBookmark().orElse(null))
- ;
+ : Objects.equals(contextBookmarkIfAny,
other.getBookmark().orElse(null));
}
// -- HELPER