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/09/01 07:38:50 UTC

[isis] branch master updated: ISIS-2861: remove ViewModel.Cloneable

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 671ab55  ISIS-2861: remove ViewModel.Cloneable
671ab55 is described below

commit 671ab557ac84692c458403c461b8d8635f6abdea
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Sep 1 09:38:37 2021 +0200

    ISIS-2861: remove ViewModel.Cloneable
---
 .../java/org/apache/isis/applib/ViewModel.java     | 106 ++++++++++-----------
 .../core/metamodel/facets/DomainEventHelper.java   |  14 +--
 ...ctionInvocationFacetForDomainEventAbstract.java |  29 +-----
 ...tyDerivedFromRecreatableObjectFacetFactory.java |  57 -----------
 ...cetOnPropertyInferredFromRecreatableObject.java |  51 ----------
 .../RecreatableObjectFacetAbstract.java            |  30 ------
 ...ableObjectFacetForXmlRootElementAnnotation.java |  20 +---
 .../metamodel/facets/object/recreatable/Util.java  |  33 -------
 .../facets/object/viewmodel/ViewModelFacet.java    |  22 -----
 ...tySetterOrClearFacetForDomainEventAbstract.java |   6 +-
 .../clear/PropertyClearFacetViaClearMethod.java    |   2 +-
 .../clear/PropertyClearFacetViaSetterMethod.java   |   2 +-
 .../modify/PropertySetterFacetViaSetterMethod.java |   2 +-
 .../DeriveDisabledFromViewModelPostProcessor.java  |  83 ----------------
 .../dflt/ProgrammingModelFacetsJava8.java          |   2 -
 .../isis/core/metamodel/spec/ManagedObjects.java   |  29 ------
 .../core/metamodel/spec/ObjectSpecification.java   |  13 +--
 .../specimpl/dflt/ObjectSpecificationDefault.java  |  12 ---
 .../testspec/ObjectSpecificationStub.java          |   5 -
 ...lWithAnnotationOptionalUsingPrivateSupport.java |   5 +-
 .../good/ViewModelWithEncapsulatedMembers.java     |   5 +-
 .../wicket/model/models/ScalarPropertyModel.java   |   4 -
 22 files changed, 74 insertions(+), 458 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/ViewModel.java b/api/applib/src/main/java/org/apache/isis/applib/ViewModel.java
index 75c8d0c..e80d66f 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/ViewModel.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/ViewModel.java
@@ -19,13 +19,7 @@
 
 package org.apache.isis.applib;
 
-import java.io.Serializable;
-
 import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.commons.internal.resources._Serializables;
-
-import lombok.SneakyThrows;
-import lombok.val;
 
 /**
  * Indicates that an object belongs to the UI/application layer, and is intended to be used as a view model.
@@ -58,56 +52,56 @@ public interface ViewModel {
     @Programmatic
     void viewModelInit(String memento);
 
-    /**
-     * Cloneable view models can in effect appear to be editable; the viewer can build a new view model from a
-     * view model whose state has been edited.
-     */
-    public interface Cloneable {
-        /**
-         *
-         * @return a copy of this object - injection points are automatically resolved by the framework
-         */
-        @Programmatic
-        Object copy();
-    }
-
-    /**
-     * Specialization of {@link ViewModel.Cloneable},
-     * that utilizes Java serialization to in-memory create ViewModel clones.
-     * @since 2.0
-     */
-    public interface CloneableViaSerialization
-    extends
-        Cloneable,
-        Serializable {
-        @Override
-        @Programmatic
-        default Object copy() {
-            val bytes = _Serializables.write(this);
-            val copy =  _Serializables.read(this.getClass(), bytes);
-            return copy;
-        }
-    }
-
-    /**
-     * Specialization of {@link ViewModel.Cloneable},
-     * that utilizes {@link ViewModel}'s mementos to in-memory create ViewModel clones.
-     * @since 2.0
-     */
-    public interface CloneableViaMemento
-    extends
-        Cloneable,
-        ViewModel {
-        @Override
-        @Programmatic
-        @SneakyThrows
-        default Object copy() {
-            val memento = this.viewModelMemento();
-            val copy =  this.getClass().getDeclaredConstructor().newInstance();
-            copy.viewModelInit(memento);
-            return copy;
-        }
-    }
+//    /**
+//     * Cloneable view models can in effect appear to be editable; the viewer can build a new view model from a
+//     * view model whose state has been edited.
+//     */
+//    public interface Cloneable {
+//        /**
+//         *
+//         * @return a copy of this object - injection points are automatically resolved by the framework
+//         */
+//        @Programmatic
+//        Object copy();
+//    }
+//
+//    /**
+//     * Specialization of {@link ViewModel.Cloneable},
+//     * that utilizes Java serialization to in-memory create ViewModel clones.
+//     * @since 2.0
+//     */
+//    public interface CloneableViaSerialization
+//    extends
+//        Cloneable,
+//        Serializable {
+//        @Override
+//        @Programmatic
+//        default Object copy() {
+//            val bytes = _Serializables.write(this);
+//            val copy =  _Serializables.read(this.getClass(), bytes);
+//            return copy;
+//        }
+//    }
+//
+//    /**
+//     * Specialization of {@link ViewModel.Cloneable},
+//     * that utilizes {@link ViewModel}'s mementos to in-memory create ViewModel clones.
+//     * @since 2.0
+//     */
+//    public interface CloneableViaMemento
+//    extends
+//        Cloneable,
+//        ViewModel {
+//        @Override
+//        @Programmatic
+//        @SneakyThrows
+//        default Object copy() {
+//            val memento = this.viewModelMemento();
+//            val copy =  this.getClass().getDeclaredConstructor().newInstance();
+//            copy.viewModelInit(memento);
+//            return copy;
+//        }
+//    }
 
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
index 7cac91c..d40a919 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
@@ -25,6 +25,8 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
+import org.springframework.lang.Nullable;
+
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.events.domain.AbstractDomainEvent;
 import org.apache.isis.applib.events.domain.ActionDomainEvent;
@@ -76,11 +78,11 @@ public class DomainEventHelper {
             final FacetHolder facetHolder,
             final InteractionHead head,
             final Can<ManagedObject> argumentAdapters,
-            final ManagedObject resultAdapter) {
+            final @Nullable Object resultPojo) {
 
         return postEventForAction(phase, uncheckedCast(eventType), /*existingEvent*/null,
                 objectAction, facetHolder,
-                head, argumentAdapters, resultAdapter);
+                head, argumentAdapters, resultPojo);
     }
 
     // variant using existing event and not eventType (is derived from event)
@@ -91,11 +93,11 @@ public class DomainEventHelper {
             final FacetHolder facetHolder,
             final InteractionHead head,
             final Can<ManagedObject> argumentAdapters,
-            final ManagedObject resultAdapter) {
+            final @Nullable Object resultPojo) {
 
         return postEventForAction(phase,
                 uncheckedCast(existingEvent.getClass()), existingEvent, objectAction, facetHolder,
-                head, argumentAdapters, resultAdapter);
+                head, argumentAdapters, resultPojo);
     }
 
     private <S> ActionDomainEvent<S> postEventForAction(
@@ -106,7 +108,7 @@ public class DomainEventHelper {
             final FacetHolder facetHolder,
             final InteractionHead head,
             final Can<ManagedObject> argumentAdapters,
-            final ManagedObject resultAdapter) {
+            final @Nullable Object resultPojo) {
 
         _Assert.assertTypeIsInstanceOf(eventType, ActionDomainEvent.class);
 
@@ -152,7 +154,7 @@ public class DomainEventHelper {
             event.setEventPhase(phase);
 
             if(phase.isExecuted()) {
-                event.setReturnValue(UnwrapUtil.single(resultAdapter));
+                event.setReturnValue(resultPojo);
             }
 
             metamodelEventService.fireActionDomainEvent(event);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
index a6b9e16..ded4285 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
@@ -43,7 +43,6 @@ import org.apache.isis.core.metamodel.facets.actions.semantics.ActionSemanticsFa
 import org.apache.isis.core.metamodel.interactions.InteractionHead;
 import org.apache.isis.core.metamodel.services.ixn.InteractionDtoFactory;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ManagedObjects;
 import org.apache.isis.core.metamodel.spec.ManagedObjects.UnwrapUtil;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
@@ -166,21 +165,6 @@ implements ImperativeFacet {
         }
     }
 
-    private ManagedObject cloneIfViewModelCloneable(
-            final Object resultPojo,
-            final ManagedObject targetAdapter) {
-
-        // to remove boilerplate from the domain, we automatically clone the returned object if it is a view model.
-
-        if (resultPojo != null) {
-            final ManagedObject resultAdapter = getObjectManager().adapt(resultPojo);
-            return ManagedObjects.copyViewModel(resultAdapter).orElse(resultAdapter);
-        } else {
-            // if void or null, attempt to clone the original target, else return null.
-            return ManagedObjects.copyViewModel(targetAdapter).orElse(null);
-        }
-    }
-
     private QueryResultsCache getQueryResultsCache() {
         return serviceRegistry.lookupServiceElseFail(QueryResultsCache.class);
     }
@@ -229,8 +213,6 @@ implements ImperativeFacet {
 
                 // invoke method
                 val resultPojo = invokeMethodElseFromCache(head, argumentAdapters);
-                ManagedObject resultAdapterPossiblyCloned =
-                        cloneIfViewModelCloneable(resultPojo, head.getTarget());
 
                 // ... post the executed event
 
@@ -238,14 +220,9 @@ implements ImperativeFacet {
                         AbstractDomainEvent.Phase.EXECUTED,
                         actionDomainEvent,
                         owningAction, owningAction, head, argumentAdapters,
-                        resultAdapterPossiblyCloned);
-
-                final Object returnValue = actionDomainEvent.getReturnValue();
-                if(returnValue != resultPojo) {
-                    resultAdapterPossiblyCloned =
-                            cloneIfViewModelCloneable(returnValue, head.getTarget());
-                }
-                return UnwrapUtil.single(resultAdapterPossiblyCloned);
+                        resultPojo);
+
+                return actionDomainEvent.getReturnValue();
 
 //            } catch (Exception e) {
 //
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/DisabledFacetOnPropertyDerivedFromRecreatableObjectFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/DisabledFacetOnPropertyDerivedFromRecreatableObjectFacetFactory.java
deleted file mode 100644
index 426af05..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/DisabledFacetOnPropertyDerivedFromRecreatableObjectFacetFactory.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.core.metamodel.facets.object.recreatable;
-
-import java.lang.reflect.Method;
-
-import javax.inject.Inject;
-
-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.members.disabled.DisabledFacetAbstract;
-import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-
-public class DisabledFacetOnPropertyDerivedFromRecreatableObjectFacetFactory
-extends FacetFactoryAbstract {
-
-    @Inject
-    public DisabledFacetOnPropertyDerivedFromRecreatableObjectFacetFactory(final MetaModelContext mmc) {
-        super(mmc, FeatureType.PROPERTIES_ONLY);
-    }
-
-    @Override
-    public void process(final ProcessMethodContext processMethodContext) {
-        final Method method = processMethodContext.getMethod();
-        final Class<?> declaringClass = method.getDeclaringClass();
-        final ObjectSpecification spec = getSpecificationLoader().loadSpecification(declaringClass);
-        if (!spec.containsNonFallbackFacet(ViewModelFacet.class)) {
-            return;
-        }
-        final ViewModelFacet facet = spec.getFacet(ViewModelFacet.class);
-        final DisabledFacetAbstract.Semantics semantics = Util.inferSemanticsFrom(facet);
-
-        final FacetedMethod facetHolder = processMethodContext.getFacetHolder();
-        addFacet(new DisabledFacetOnPropertyInferredFromRecreatableObject(facetHolder, semantics));
-    }
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/DisabledFacetOnPropertyInferredFromRecreatableObject.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/DisabledFacetOnPropertyInferredFromRecreatableObject.java
deleted file mode 100644
index f0c6464..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/DisabledFacetOnPropertyInferredFromRecreatableObject.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.core.metamodel.facets.object.recreatable;
-
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacetAbstract;
-import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
-
-import lombok.val;
-
-public class DisabledFacetOnPropertyInferredFromRecreatableObject
-extends DisabledFacetAbstract {
-
-    public DisabledFacetOnPropertyInferredFromRecreatableObject(
-            final FacetHolder holder,
-            final Semantics semantics) {
-        super(Where.ANYWHERE,
-                "calculated at runtime, based on whether viewmodel is cloneable",
-                holder, semantics, Precedence.INFERRED);
-    }
-
-    @Override
-    public String disabledReason(final ManagedObject target) {
-        val viewModelFacet = target.getSpecification().getFacet(ViewModelFacet.class);
-        val isCloneable = viewModelFacet.isCloneable(target.getPojo());
-        if (!isCloneable) {
-            return "Non-cloneable view models are read-only";
-        }
-        return null;
-    }
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetAbstract.java
index 599c214..08ad1f5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetAbstract.java
@@ -22,8 +22,6 @@ package org.apache.isis.core.metamodel.facets.object.recreatable;
 import java.lang.reflect.Method;
 import java.util.function.BiConsumer;
 
-import org.apache.isis.applib.ViewModel;
-import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.core.metamodel.commons.ClassExtensions;
 import org.apache.isis.core.metamodel.commons.MethodExtensions;
@@ -32,7 +30,6 @@ import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.PostConstructMethodCache;
 import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 
 import lombok.val;
 
@@ -66,33 +63,6 @@ implements ViewModelFacet {
         this.recreationMechanism = recreationMechanism;
     }
 
-
-    @Override
-    public boolean isCloneable(final Object pojo) {
-        return pojo != null && pojo instanceof ViewModel.Cloneable;
-    }
-
-    @Override
-    public boolean isImplicitlyImmutable() {
-        final FacetHolder facetHolder = getFacetHolder();
-        if (facetHolder instanceof ObjectSpecification) {
-            final ObjectSpecification objectSpec = (ObjectSpecification) facetHolder;
-            final Class<?> correspondingClass = objectSpec.getCorrespondingClass();
-            if (ViewModel.Cloneable.class.isAssignableFrom(correspondingClass)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public <T> T cloneViewModelPojo(final T pojo) {
-        ViewModel.Cloneable viewModelCloneable = (ViewModel.Cloneable) pojo;
-        val copy = viewModelCloneable.copy();
-        return _Casts.uncheckedCast(
-                getServiceInjector().injectServicesInto(copy));
-    }
-
     @Override
     public RecreationMechanism getRecreationMechanism() {
         return recreationMechanism;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetForXmlRootElementAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetForXmlRootElementAnnotation.java
index 889bf0f..fc2142c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetForXmlRootElementAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetForXmlRootElementAnnotation.java
@@ -21,7 +21,6 @@ package org.apache.isis.core.metamodel.facets.object.recreatable;
 
 import org.apache.isis.applib.services.jaxb.JaxbService;
 import org.apache.isis.applib.services.urlencoding.UrlEncodingService;
-import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.PostConstructMethodCache;
 
@@ -54,24 +53,7 @@ extends RecreatableObjectFacetAbstract {
         return encoded;
     }
 
-    @Override
-    public boolean isCloneable(final Object pojo) {
-        return true;
-    }
-
-    @Override
-    public boolean isImplicitlyImmutable() {
-        return false;
-    }
-
-    @Override
-    public <T> T cloneViewModelPojo(final T pojo) {
-        final String xml = getJaxbService().toXml(pojo);
-        final Object cloned = getJaxbService().fromXml(pojo.getClass(), xml);
-        return _Casts.uncheckedCast(
-                getServiceInjector().injectServicesInto(cloned));
-    }
-
+    // -- DEPENDENCIES
 
     private JaxbService getJaxbService() {
         return getServiceRegistry().lookupServiceElseFail(JaxbService.class);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/Util.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/Util.java
deleted file mode 100644
index dc92aa8..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/Util.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.facets.object.recreatable;
-
-import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacetAbstract;
-import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
-
-class Util {
-    private Util() {
-    }
-
-    static DisabledFacetAbstract.Semantics inferSemanticsFrom(final ViewModelFacet facet) {
-        return facet.isImplicitlyImmutable() ?
-                DisabledFacetAbstract.Semantics.DISABLED :
-                    DisabledFacetAbstract.Semantics.ENABLED;
-    }
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacet.java
index be4b34f..b5d11a1 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacet.java
@@ -102,26 +102,4 @@ public interface ViewModelFacet extends Facet {
      */
     String memento(Object viewModelPojo);
 
-    /**
-     * Whether {@link #cloneViewModelPojo(Object)} can be called.
-     */
-    boolean isCloneable(Object viewModelPojo);
-
-    /**
-     * Whether can infer the view model is immutable or not.
-     *
-     * <p>
-     *     Equivalent to {@link #isCloneable(Object)}, but at the class rather than object level.
-     * </p>
-     */
-    boolean isImplicitlyImmutable();
-
-    /**
-     * View models are implicitly immutable (their state is determined by their {@link #memento(Object)}), so this
-     * method allows the framework to clone an existing view model to mutate it, thereby simulating editable
-     * view models.
-     * @return a clone of the argument with injection points resolved
-     */
-    <T> T cloneViewModelPojo(T viewModelPojo);
-
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
index 15a9c84..d455910 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
@@ -39,7 +39,6 @@ import org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySe
 import org.apache.isis.core.metamodel.interactions.InteractionHead;
 import org.apache.isis.core.metamodel.services.ixn.InteractionDtoFactory;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ManagedObjects;
 import org.apache.isis.core.metamodel.spec.ManagedObjects.UnwrapUtil;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 
@@ -232,10 +231,7 @@ implements
                             oldValuePojo, actualNewValue);
                 }
 
-                val targetManagedObjectPossiblyCloned =
-                        ManagedObjects.copyViewModel(head.getTarget()).orElse(head.getTarget());
-
-                return targetManagedObjectPossiblyCloned.getPojo();
+                return head.getTarget().getPojo();
 
                 //
                 // REVIEW: the corresponding action has a whole bunch of error handling here.
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaClearMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaClearMethod.java
index a567d61..37e34cb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaClearMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaClearMethod.java
@@ -57,7 +57,7 @@ implements ImperativeFacet {
             final InteractionInitiatedBy interactionInitiatedBy) {
         val method = methods.getFirstOrFail();
         ManagedObjects.InvokeUtil.invoke(method, targetAdapter);
-        return ManagedObjects.copyViewModel(targetAdapter).orElse(targetAdapter);
+        return targetAdapter;
     }
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaSetterMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaSetterMethod.java
index fa0be27..71b60ed 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaSetterMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaSetterMethod.java
@@ -58,7 +58,7 @@ implements ImperativeFacet {
 
         val method = methods.getFirstOrFail();
         ManagedObjects.InvokeUtil.invoke(method, targetAdapter);
-        return ManagedObjects.copyViewModel(targetAdapter).orElse(targetAdapter);
+        return targetAdapter;
     }
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaSetterMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaSetterMethod.java
index d18fc73..15fdafc 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaSetterMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaSetterMethod.java
@@ -59,7 +59,7 @@ implements ImperativeFacet {
 
         val method = methods.getFirstOrFail();
         ManagedObjects.InvokeUtil.invoke(method, targetAdapter, valueAdapter);
-        return ManagedObjects.copyViewModel(targetAdapter).orElse(targetAdapter);
+        return targetAdapter;
     }
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/properties/DeriveDisabledFromViewModelPostProcessor.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/properties/DeriveDisabledFromViewModelPostProcessor.java
deleted file mode 100644
index 117fad2..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/properties/DeriveDisabledFromViewModelPostProcessor.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.core.metamodel.postprocessors.properties;
-
-import javax.inject.Inject;
-
-import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.facetapi.FacetUtil;
-import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacet;
-import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacetAbstract;
-import org.apache.isis.core.metamodel.facets.object.recreatable.DisabledFacetOnPropertyDerivedFromRecreatableObjectFacetFactory;
-import org.apache.isis.core.metamodel.facets.object.recreatable.DisabledFacetOnPropertyInferredFromRecreatableObject;
-import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
-import org.apache.isis.core.metamodel.postprocessors.ObjectSpecificationPostProcessorAbstract;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-
-
-/**
- * Replaces {@link DisabledFacetOnPropertyDerivedFromRecreatableObjectFacetFactory}
- */
-public class DeriveDisabledFromViewModelPostProcessor
-extends ObjectSpecificationPostProcessorAbstract {
-
-    @Inject
-    public DeriveDisabledFromViewModelPostProcessor(final MetaModelContext metaModelContext) {
-        super(metaModelContext);
-    }
-
-    @Override
-    protected void doPostProcess(final ObjectSpecification objectSpecification) {
-    }
-
-    @Override
-    protected void doPostProcess(final ObjectSpecification objectSpecification, final ObjectAction act) {
-    }
-
-    @Override
-    protected void doPostProcess(final ObjectSpecification objectSpecification, final ObjectAction objectAction, final ObjectActionParameter param) {
-    }
-
-    @Override
-    protected void doPostProcess(final ObjectSpecification objectSpecification, final OneToOneAssociation property) {
-        if(property.containsNonFallbackFacet(DisabledFacet.class)){
-            return;
-        }
-        property.getOnType()
-        .lookupNonFallbackFacet(ViewModelFacet.class)
-        .ifPresent(specFacet -> FacetUtil.addFacet(new DisabledFacetOnPropertyInferredFromRecreatableObject(
-                                    facetedMethodFor(property), inferSemanticsFrom(specFacet))));
-    }
-
-    @Override
-    protected void doPostProcess(final ObjectSpecification objectSpecification, final OneToManyAssociation coll) {
-    }
-
-    static DisabledFacetAbstract.Semantics inferSemanticsFrom(final ViewModelFacet facet) {
-        return facet.isImplicitlyImmutable()
-                ? DisabledFacetAbstract.Semantics.DISABLED
-                : DisabledFacetAbstract.Semantics.ENABLED;
-    }
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodels/dflt/ProgrammingModelFacetsJava8.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodels/dflt/ProgrammingModelFacetsJava8.java
index 82b2ba8..854c3d1 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodels/dflt/ProgrammingModelFacetsJava8.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodels/dflt/ProgrammingModelFacetsJava8.java
@@ -152,7 +152,6 @@ import org.apache.isis.core.metamodel.postprocessors.members.TweakDomainEventsFo
 import org.apache.isis.core.metamodel.postprocessors.members.navigation.DeriveNavigationFacetFromHiddenTypePostProcessor;
 import org.apache.isis.core.metamodel.postprocessors.object.DeriveProjectionFacetsPostProcessor;
 import org.apache.isis.core.metamodel.postprocessors.properties.DeriveDisabledFromImmutablePostProcessor;
-import org.apache.isis.core.metamodel.postprocessors.properties.DeriveDisabledFromViewModelPostProcessor;
 import org.apache.isis.core.metamodel.postprocessors.propparam.DeriveChoicesFromExistingChoicesPostProcessor;
 import org.apache.isis.core.metamodel.postprocessors.propparam.DeriveDefaultFromTypePostProcessor;
 import org.apache.isis.core.metamodel.postprocessors.propparam.DeriveTypicalLengthFromTypePostProcessor;
@@ -391,7 +390,6 @@ extends ProgrammingModelAbstract {
         addPostProcessor(PostProcessingOrder.A1_BUILTIN, new DeriveDefaultFromTypePostProcessor(mmc));
         addPostProcessor(PostProcessingOrder.A1_BUILTIN, new DeriveChoicesFromExistingChoicesPostProcessor(mmc));
         addPostProcessor(PostProcessingOrder.A1_BUILTIN, new DeriveDisabledFromImmutablePostProcessor(mmc));
-        addPostProcessor(PostProcessingOrder.A1_BUILTIN, new DeriveDisabledFromViewModelPostProcessor(mmc));
         addPostProcessor(PostProcessingOrder.A1_BUILTIN, new DeriveCollectionParamDefaultsAndChoicesPostProcessor(mmc));
         addPostProcessor(PostProcessingOrder.A1_BUILTIN, new TweakDomainEventsForMixinPostProcessor(mmc));
         addPostProcessor(PostProcessingOrder.A1_BUILTIN, new DeriveProjectionFacetsPostProcessor(mmc));
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
index 2e1ea22..ed7cdb4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
@@ -55,7 +55,6 @@ import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facets.collections.CollectionFacet;
 import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
 import org.apache.isis.core.metamodel.facets.object.entity.PersistenceStandard;
-import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
 import org.apache.isis.core.metamodel.interactions.InteractionHead;
 import org.apache.isis.core.metamodel.interactions.InteractionUtils;
 import org.apache.isis.core.metamodel.interactions.ObjectVisibilityContext;
@@ -216,34 +215,6 @@ public final class ManagedObjects {
 
     };
 
-    // -- COPY UTILITIES
-
-    /**
-     * Optionally returns a new ManagedObject wrapping a clone of the given ViewModel,
-     * with injection points resolved,
-     * based on whether given {@code viewModel} is a clone-able ViewModel.
-     */
-    @Nullable
-    public static Optional<ManagedObject> copyViewModel(final @Nullable ManagedObject viewModel) {
-
-        if(viewModel==null) {
-            return Optional.empty();
-        }
-
-        val viewModelFacet = viewModel.getSpecification().getFacet(ViewModelFacet.class);
-        if(viewModelFacet != null) {
-            val viewModelPojo = viewModel.getPojo();
-            if(viewModelFacet.isCloneable(viewModelPojo)) {
-                return Optional.of(ManagedObject.of(
-                        viewModel.getSpecification(),
-                        viewModelFacet.cloneViewModelPojo(viewModelPojo)));
-            }
-        }
-
-        return Optional.empty();
-
-    }
-
     // -- DEFAULTS UTILITIES
 
     public static ManagedObject emptyToDefault(final boolean mandatory, final @NonNull ManagedObject input) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
index 39cf2b4..6aa4142 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
@@ -19,7 +19,6 @@
 
 package org.apache.isis.core.metamodel.spec;
 
-import java.io.Externalizable;
 import java.io.Serializable;
 import java.lang.reflect.Array;
 import java.lang.reflect.Method;
@@ -421,7 +420,6 @@ extends
         return getBeanSort().isMixin();
     }
 
-    boolean isViewModelCloneable(ManagedObject targetAdapter);
     boolean isWizard();
 
     //TODO this predicate can now be answered by getBeanSort().isAbstract(), we can retire any old logic
@@ -466,8 +464,8 @@ extends
 
         final Object newInstance;
         try {
-            newInstance = cls.newInstance();
-        } catch (final IllegalAccessException | InstantiationException e) {
+            newInstance = cls.getDeclaredConstructor().newInstance();
+        } catch (final Throwable e) {
             throw new UnrecoverableException("Failed to create instance of type " + getFullIdentifier(), e);
         }
 
@@ -559,17 +557,14 @@ extends
     }
 
     /**
-     * @return whether corresponding class implements {@link java.io.Serializable} or
-     * {@link java.io.Externalizable}.
+     * @return whether corresponding class implements {@link java.io.Serializable}.
      * @apiNote: per se does not tell what recreation strategy to use, the corresponding class
      * might be an entity or a view-model or a value with eg. encodable semantics, which have
      * different object recreation mechanics
      * @since 2.0.0
      */
     default boolean isSerializable() {
-        return
-                Serializable.class.isAssignableFrom(getCorrespondingClass())
-                || Externalizable.class.isAssignableFrom(getCorrespondingClass());
+        return Serializable.class.isAssignableFrom(getCorrespondingClass());
     }
 
     default String fqcn() {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
index a2830ca..b340177 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
@@ -47,12 +47,10 @@ import org.apache.isis.core.metamodel.facets.all.named.MemberNamedFacet;
 import org.apache.isis.core.metamodel.facets.all.named.MemberNamedFacetForStaticMemberName;
 import org.apache.isis.core.metamodel.facets.object.introspection.IntrospectionPolicyFacet;
 import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
-import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
 import org.apache.isis.core.metamodel.facets.object.wizard.WizardFacet;
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutorRegistry;
 import org.apache.isis.core.metamodel.spec.ActionType;
 import org.apache.isis.core.metamodel.spec.ElementSpecificationProvider;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.MixedIn;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
@@ -254,16 +252,6 @@ implements FacetHolder {
     // -- PREDICATES
 
     @Override
-    public boolean isViewModelCloneable(final ManagedObject targetAdapter) {
-        final ViewModelFacet facet = getFacet(ViewModelFacet.class);
-        if(facet == null) {
-            return false;
-        }
-        final Object pojo = targetAdapter.getPojo();
-        return facet.isCloneable(pojo);
-    }
-
-    @Override
     public boolean isWizard() {
         return containsFacet(WizardFacet.class);
     }
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
index fb46b4f..1035be5 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
@@ -319,11 +319,6 @@ implements ObjectSpecification {
     // /////////////////////////////////////////////////////////
 
     @Override
-    public boolean isViewModelCloneable(final ManagedObject targetAdapter) {
-        return false;
-    }
-
-    @Override
     public boolean isWizard() {
         return false;
     }
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ViewModelWithAnnotationOptionalUsingPrivateSupport.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ViewModelWithAnnotationOptionalUsingPrivateSupport.java
index fb06d95..4db5a3d 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ViewModelWithAnnotationOptionalUsingPrivateSupport.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ViewModelWithAnnotationOptionalUsingPrivateSupport.java
@@ -18,9 +18,9 @@
  */
 package org.apache.isis.testdomain.model.good;
 
+import java.io.Serializable;
 import java.util.List;
 
-import org.apache.isis.applib.ViewModel;
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.Collection;
 import org.apache.isis.applib.annotation.DomainObject;
@@ -42,8 +42,7 @@ import lombok.Setter;
         nature = Nature.VIEW_MODEL,
         introspection = Introspection.ANNOTATION_OPTIONAL)
 public class ViewModelWithAnnotationOptionalUsingPrivateSupport
-implements
-    ViewModel.CloneableViaSerialization {
+implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ViewModelWithEncapsulatedMembers.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ViewModelWithEncapsulatedMembers.java
index 6056f4a..32e46a7 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ViewModelWithEncapsulatedMembers.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ViewModelWithEncapsulatedMembers.java
@@ -18,9 +18,9 @@
  */
 package org.apache.isis.testdomain.model.good;
 
+import java.io.Serializable;
 import java.util.List;
 
-import org.apache.isis.applib.ViewModel;
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.Collection;
 import org.apache.isis.applib.annotation.DomainObject;
@@ -37,8 +37,7 @@ import lombok.Setter;
         nature = Nature.VIEW_MODEL,
         introspection = Introspection.ENCAPSULATION_ENABLED)
 public class ViewModelWithEncapsulatedMembers
-implements
-    ViewModel.CloneableViaSerialization {
+implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarPropertyModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarPropertyModel.java
index ac17e97..f7fff17 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarPropertyModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarPropertyModel.java
@@ -19,7 +19,6 @@
 package org.apache.isis.viewer.wicket.model.models;
 
 import org.apache.isis.commons.collections.Can;
-import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
 import org.apache.isis.core.metamodel.interactions.managed.InteractionVeto;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedProperty;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
@@ -163,14 +162,11 @@ implements PropertyUiModel {
      * Apply changes to the underlying adapter (possibly returning a new adapter).
      *
      * @return adapter, which may be different from the original
-     *  (specifically, if operating on a {@link ViewModelFacet#isCloneable(Object) cloneable} view model, for example.
      */
     public ManagedObject applyValue() {
-
         val proposedNewValue = getObject();
         getManagedProperty().modifyProperty(proposedNewValue);
         return getManagedProperty().getOwner();
-
     }
 
     @Override