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 2018/09/04 20:26:00 UTC
[isis] 18/24: ISIS-1976: let PersistenceSession no longer implement
AdapterManager
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch ISIS-1976-rethink-object-adapters
in repository https://gitbox.apache.org/repos/asf/isis.git
commit 9ef889fdbc7909ffc0db48256ebf7c36b3cb28fc
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Sep 4 05:34:57 2018 +0200
ISIS-1976: let PersistenceSession no longer implement AdapterManager
Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
.../core/metamodel/adapter/mgr/AdapterManager.java | 87 +++--
.../system/persistence/IsisLifecycleListener.java | 5 +-
.../system/persistence/PersistenceSession5.java | 369 +++------------------
.../PersistenceSession5_ObjectAdapterProvider.java | 140 ++++++++
.../queries/PersistenceQueryProcessorAbstract.java | 3 +-
.../apache/isis/core/runtime/memento/Memento.java | 3 +-
.../system/persistence/PersistenceSession.java | 40 ++-
.../adaptermanager/ObjectAdapterContext.java | 64 +++-
.../ObjectAdapterContext_AdapterManager.java | 189 +++++++++++
.../ObjectAdapterContext_Consistency.java | 119 +++++++
.../ObjectAdapterContext_MementoSupport.java | 246 ++++++++++++++
.../adaptermanager/ObjectAdapterLegacy.java | 212 ------------
.../adaptermanager/RootAndCollectionAdapters.java | 8 +-
.../wicket/ConverterForObjectAdapter.java | 8 +-
.../wicket/ConverterForObjectAdapterMemento.java | 8 +-
15 files changed, 894 insertions(+), 607 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/mgr/AdapterManager.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/mgr/AdapterManager.java
index 0284fbe..70ad13e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/mgr/AdapterManager.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/mgr/AdapterManager.java
@@ -23,11 +23,8 @@ import java.util.concurrent.Callable;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
-import org.apache.isis.core.metamodel.adapter.oid.Oid;
-public interface AdapterManager extends ObjectAdapterProvider {
+public interface AdapterManager /*extends ObjectAdapterProvider*/ {
enum ConcurrencyChecking {
@@ -122,46 +119,46 @@ public interface AdapterManager extends ObjectAdapterProvider {
// -- DEPRECATIONS
- /**
- * Enable RecreatableObjectFacet to 'temporarily' map an existing pojo to an oid.
- * @deprecated don't expose caching
- */
- @Programmatic @Deprecated
- ObjectAdapter addRecreatedPojoToCache(Oid oid, Object recreatedPojo);
-
- /**
- * Enable RecreatableObjectFacet to remove a 'temporarily' mapped adapter for a pojo.
- * @deprecated don't expose caching
- */
- @Programmatic @Deprecated
- void removeAdapterFromCache(ObjectAdapter adapter);
-
-
- /**
- * Gets the {@link ObjectAdapter adapter} for the specified domain object if
- * it exists in the identity map.
- *
- * <p>
- * Provided by the <tt>AdapterManager</tt> when used by framework.
- *
- * @param pojo
- * - must not be <tt>null</tt>
- * @return adapter, or <tt>null</tt> if doesn't exist.
- * @deprecated don't expose caching
- */
- @Programmatic @Deprecated
- ObjectAdapter lookupAdapterFor(Object pojo);
-
- /**
- * Gets the {@link ObjectAdapter adapter} for the {@link Oid} if it exists
- * in the identity map.
- *
- * @param oid
- * - must not be <tt>null</tt>
- * @return adapter, or <tt>null</tt> if doesn't exist.
- * @deprecated don't expose caching
- */
- @Programmatic @Deprecated
- ObjectAdapter lookupAdapterFor(Oid oid);
+// /**
+// * Enable RecreatableObjectFacet to 'temporarily' map an existing pojo to an oid.
+// * @deprecated don't expose caching
+// */
+// @Programmatic @Deprecated
+// ObjectAdapter addRecreatedPojoToCache(Oid oid, Object recreatedPojo);
+//
+// /**
+// * Enable RecreatableObjectFacet to remove a 'temporarily' mapped adapter for a pojo.
+// * @deprecated don't expose caching
+// */
+// @Programmatic @Deprecated
+// void removeAdapterFromCache(ObjectAdapter adapter);
+//
+//
+// /**
+// * Gets the {@link ObjectAdapter adapter} for the specified domain object if
+// * it exists in the identity map.
+// *
+// * <p>
+// * Provided by the <tt>AdapterManager</tt> when used by framework.
+// *
+// * @param pojo
+// * - must not be <tt>null</tt>
+// * @return adapter, or <tt>null</tt> if doesn't exist.
+// * @deprecated don't expose caching
+// */
+// @Programmatic @Deprecated
+// ObjectAdapter lookupAdapterFor(Object pojo);
+//
+// /**
+// * Gets the {@link ObjectAdapter adapter} for the {@link Oid} if it exists
+// * in the identity map.
+// *
+// * @param oid
+// * - must not be <tt>null</tt>
+// * @return adapter, or <tt>null</tt> if doesn't exist.
+// * @deprecated don't expose caching
+// */
+// @Programmatic @Deprecated
+// ObjectAdapter lookupAdapterFor(Oid oid);
}
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/IsisLifecycleListener.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/IsisLifecycleListener.java
index 6634947..9713474 100644
--- a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/IsisLifecycleListener.java
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/IsisLifecycleListener.java
@@ -34,6 +34,8 @@ import com.google.common.collect.Maps;
import org.datanucleus.enhancement.Persistable;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+
public class IsisLifecycleListener
implements AttachLifecycleListener, ClearLifecycleListener, CreateLifecycleListener, DeleteLifecycleListener,
DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLifecycleListener,
@@ -45,13 +47,12 @@ SuspendableListener {
interface PersistenceSessionLifecycleManagement {
void ensureRootObject(Persistable pojo);
- void initializeMapAndCheckConcurrency(Persistable pojo);
+ ObjectAdapter initializeMapAndCheckConcurrency(Persistable pojo);
void enlistCreatedAndRemapIfRequiredThenInvokeIsisInvokePersistingOrUpdatedCallback(Persistable pojo);
void invokeIsisPersistingCallback(Persistable pojo);
void enlistUpdatingAndInvokeIsisUpdatingCallback(Persistable pojo);
void enlistDeletingAndInvokeIsisRemovingCallbackFacet(Persistable pojo);
- //ObjectAdapter getAdapterFor(Persistable pojo);
}
private final PersistenceSessionLifecycleManagement persistenceSession;
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5.java
index 6e278a2..9910f32 100644
--- a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5.java
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5.java
@@ -19,8 +19,6 @@
package org.apache.isis.core.runtime.system.persistence;
import static org.apache.isis.commons.internal.base._Casts.uncheckedCast;
-import static org.apache.isis.commons.internal.functions._Predicates.equalTo;
-import static org.apache.isis.core.commons.ensure.Ensure.ensureThatArg;
import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
@@ -57,7 +55,6 @@ import org.apache.isis.applib.services.bookmark.BookmarkService;
import org.apache.isis.applib.services.command.Command;
import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
import org.apache.isis.applib.services.iactn.Interaction;
-import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.commons.internal.collections._Lists;
import org.apache.isis.commons.internal.collections._Maps;
import org.apache.isis.core.commons.authentication.AuthenticationSession;
@@ -65,7 +62,9 @@ import org.apache.isis.core.commons.ensure.Assert;
import org.apache.isis.core.commons.exceptions.IsisException;
import org.apache.isis.core.commons.factory.InstanceUtil;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
import org.apache.isis.core.metamodel.adapter.oid.Oid;
import org.apache.isis.core.metamodel.adapter.oid.ParentedCollectionOid;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
@@ -88,7 +87,6 @@ import org.apache.isis.core.metamodel.facets.object.callbacks.UpdatedCallbackFac
import org.apache.isis.core.metamodel.facets.object.callbacks.UpdatedLifecycleEventFacet;
import org.apache.isis.core.metamodel.facets.object.callbacks.UpdatingCallbackFacet;
import org.apache.isis.core.metamodel.facets.object.callbacks.UpdatingLifecycleEventFacet;
-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.services.ServicesInjector;
import org.apache.isis.core.metamodel.services.container.query.QueryCardinality;
@@ -97,7 +95,6 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecId;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.Contributed;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
import org.apache.isis.core.runtime.persistence.FixturesInstalledFlag;
import org.apache.isis.core.runtime.persistence.NotPersistableException;
import org.apache.isis.core.runtime.persistence.ObjectNotFoundException;
@@ -111,6 +108,7 @@ import org.apache.isis.core.runtime.persistence.query.PersistenceQueryFindAllIns
import org.apache.isis.core.runtime.persistence.query.PersistenceQueryFindUsingApplibQueryDefault;
import org.apache.isis.core.runtime.services.RequestScopedService;
import org.apache.isis.core.runtime.system.persistence.adaptermanager.ObjectAdapterContext;
+import org.apache.isis.core.runtime.system.persistence.adaptermanager.ObjectAdapterContext.MementoRecreateObjectSupport;
import org.apache.isis.core.runtime.system.persistence.adaptermanager.ObjectAdapterLegacy;
import org.apache.isis.core.runtime.system.transaction.IsisTransaction;
import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
@@ -133,6 +131,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
private static final Logger LOG = LoggerFactory.getLogger(PersistenceSession5.class);
private ObjectAdapterContext objectAdapterContext;
+ private PersistenceSession5_ObjectAdapterProvider objectAdapterProviderMixin;
/**
* Initialize the object store so that calls to this object store access
@@ -162,7 +161,8 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
}
objectAdapterContext = ObjectAdapterLegacy.openContext(servicesInjector, authenticationSession, specificationLoader, this);
-
+ objectAdapterProviderMixin = new PersistenceSession5_ObjectAdapterProvider(this, objectAdapterContext);
+
persistenceManager = jdoPersistenceManagerFactory.getPersistenceManager();
final IsisLifecycleListener.PersistenceSessionLifecycleManagement psLifecycleMgmt = this;
@@ -244,13 +244,13 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
}
}
}
-
+
@Override
public List<ObjectAdapter> getServices() {
final List<Object> services = servicesInjector.getRegisteredServices();
final List<ObjectAdapter> serviceAdapters = _Lists.newArrayList();
for (final Object servicePojo : services) {
- ObjectAdapter serviceAdapter = lookupAdapterFor(servicePojo);
+ ObjectAdapter serviceAdapter = objectAdapterContext.lookupAdapterFor(servicePojo);
if(serviceAdapter == null) {
throw new IllegalStateException("ObjectAdapter for service " + servicePojo + " does not exist?!?");
}
@@ -382,9 +382,6 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
interaction.clear();
}
-
-
-
// -- QuerySubmitter impl, findInstancesInTransaction
@Override
public <T> List<ObjectAdapter> allMatchingQuery(final Query<T> query) {
@@ -724,7 +721,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
Objects.requireNonNull(oid);
- final ObjectAdapter adapter = lookupAdapterFor(oid);
+ final ObjectAdapter adapter = objectAdapterContext.lookupAdapterFor(oid);
if (adapter != null) {
return adapter;
}
@@ -736,14 +733,11 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
LOG.debug("getObject; oid={}", oid);
final Object pojo = loadPersistentPojo(oid);
- return addRecreatedPojoToCache(oid, pojo);
+ return objectAdapterContext.addRecreatedPojoToCache(oid, pojo);
}
});
}
-
-
-
// -- loadPersistentPojo
private Object loadPersistentPojo(final RootOid rootOid) {
@@ -844,18 +838,16 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
// -- lazilyLoaded
- private ObjectAdapter mapPersistent(final Persistable pojo) {
+ ObjectAdapter mapPersistent(final Persistable pojo) {
if (persistenceManager.getObjectId(pojo) == null) {
return null;
}
final RootOid oid = createPersistentOrViewModelOid(pojo);
- final ObjectAdapter adapter = addRecreatedPojoToCache(oid, pojo);
+ final ObjectAdapter adapter = objectAdapterContext.addRecreatedPojoToCache(oid, pojo);
return adapter;
}
-
-
// -- refreshRootInTransaction, refreshRoot, resolve
/**
@@ -1089,10 +1081,10 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
@Override
public ObjectAdapter getAggregateRoot(final ParentedCollectionOid collectionOid) {
final Oid rootOid = collectionOid.getRootOid();
- ObjectAdapter rootadapter = lookupAdapterFor(rootOid);
+ ObjectAdapter rootadapter = objectAdapterContext.lookupAdapterFor(rootOid);
if(rootadapter == null) {
final Oid parentOidNowPersisted = remappedFrom(rootOid);
- rootadapter = lookupAdapterFor(parentOidNowPersisted);
+ rootadapter = objectAdapterContext.lookupAdapterFor(parentOidNowPersisted);
}
return rootadapter;
}
@@ -1108,133 +1100,6 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
// -- AdapterManager implementation
@Override
- public ObjectAdapter lookupAdapterFor(final Object pojo) {
- Objects.requireNonNull(pojo);
-
- return objectAdapterContext.lookupAdapterByPojo(pojo);
- }
-
- @Override
- public ObjectAdapter lookupAdapterFor(final Oid oid) {
- Objects.requireNonNull(oid);
- ensureMapsConsistent(oid);
-
- return objectAdapterContext.lookupAdapterById(oid);
- }
-
-
- private ObjectAdapter existingOrValueAdapter(Object pojo) {
-
- // attempt to locate adapter for the pojo
- ObjectAdapter adapter = lookupAdapterFor(pojo);
- if (adapter != null) {
- return adapter;
- }
-
- // pojo may have been lazily loaded by object store, but we haven't yet seen it
- if (pojo instanceof Persistable) {
- adapter = mapPersistent((Persistable) pojo);
-
- // TODO: could return null if the pojo passed in !dnIsPersistent() || !dnIsDetached()
- // in which case, we would ought to map as a transient object, rather than fall through and treat as a value?
- } else {
- adapter = null;
- }
-
- if(adapter != null) {
- return adapter;
- }
-
- // need to create (and possibly map) the adapter.
- final ObjectSpecification objSpec = specificationLoader.loadSpecification(pojo.getClass());
-
- // we create value facets as standalone (so not added to maps)
- if (objSpec.containsFacet(ValueFacet.class)) {
- adapter = objectAdapterContext.getFactories().createStandaloneAdapter(pojo);
- return adapter;
- }
-
- return null;
- }
-
-
-
- /**
- * Fail early if any problems.
- */
- private void ensureMapsConsistent(final ObjectAdapter adapter) {
- if (adapter.isValue()) {
- return;
- }
- if (adapter.isParentedCollection()) {
- return;
- }
- ensurePojoAdapterMapConsistent(adapter);
- ensureOidAdapterMapConsistent(adapter);
- }
-
- /**
- * Fail early if any problems.
- * @deprecated https://issues.apache.org/jira/browse/ISIS-1976
- */
- @Deprecated
- private void ensureMapsConsistent(final Oid oid) {
- Objects.requireNonNull(oid);
-
- final ObjectAdapter adapter = objectAdapterContext.lookupAdapterById(oid);
- if (adapter == null) {
- return;
- }
- ensureOidAdapterMapConsistent(adapter);
- ensurePojoAdapterMapConsistent(adapter);
- }
-
- private void ensurePojoAdapterMapConsistent(final ObjectAdapter adapter) {
- final Object adapterPojo = adapter.getObject();
- final ObjectAdapter adapterAccordingToMap = objectAdapterContext.lookupAdapterByPojo(adapterPojo);
-
- if(adapterPojo == null) {
- // nothing to check
- return;
- }
- ensureMapConsistent(adapter, adapterAccordingToMap, "PojoAdapterMap");
- }
-
- private void ensureOidAdapterMapConsistent(final ObjectAdapter adapter) {
- final Oid adapterOid = adapter.getOid();
- final ObjectAdapter adapterAccordingToMap = objectAdapterContext.lookupAdapterById(adapterOid);
-
- if(adapterOid == null) {
- // nothing to check
- return;
- }
- ensureMapConsistent(adapter, adapterAccordingToMap, "OidAdapterMap");
- }
-
- private void ensureMapConsistent(
- final ObjectAdapter adapter,
- final ObjectAdapter adapterAccordingToMap,
- final String mapName) {
-
- final Oid adapterOid = adapter.getOid();
-
- // take care not to touch the pojo, since it might have been deleted.
-
- if(adapterAccordingToMap == null) {
- throw new IllegalStateException("mismatch in "
- + mapName
- + ": provided adapter's OID: " + adapterOid + "; but no adapter found in map");
- }
-
- ensureThatArg(
- adapter, equalTo(adapterAccordingToMap),
- ()->"mismatch in "
- + mapName
- + ": provided adapter's OID: " + adapterOid + ", \n"
- + "but map's adapter's OID was: " + adapterAccordingToMap.getOid());
- }
-
- @Override
public ObjectAdapter adapterForAny(RootOid rootOid) {
final ObjectSpecId specId = rootOid.getObjectSpecId();
@@ -1272,24 +1137,24 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
@Override
public Map<RootOid, ObjectAdapter> adaptersFor(final List<RootOid> rootOids) {
- return adaptersFor(rootOids, ConcurrencyChecking.NO_CHECK);
+ return adaptersFor(rootOids, AdapterManager.ConcurrencyChecking.NO_CHECK);
}
private Map<RootOid,ObjectAdapter> adaptersFor(
final List<RootOid> rootOids,
- final ConcurrencyChecking concurrencyChecking) {
+ final AdapterManager.ConcurrencyChecking concurrencyChecking) {
final Map<RootOid, ObjectAdapter> adapterByOid = _Maps.newLinkedHashMap();
List<RootOid> notYetLoadedOids = _Lists.newArrayList();
for (RootOid rootOid : rootOids) {
// attempt to locate adapter for the Oid
- ObjectAdapter adapter = lookupAdapterFor(rootOid);
+ ObjectAdapter adapter = objectAdapterContext.lookupAdapterFor(rootOid);
// handle view models or transient
if (adapter == null) {
if (rootOid.isTransient() || rootOid.isViewModel()) {
final Object pojo = recreatePojoTransientOrViewModel(rootOid);
- adapter = addRecreatedPojoToCache(rootOid, pojo);
+ adapter = objectAdapterContext.addRecreatedPojoToCache(rootOid, pojo);
sync(concurrencyChecking, adapter, rootOid);
}
}
@@ -1309,7 +1174,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
if(pojo != null) {
ObjectAdapter adapter;
try {
- adapter = addRecreatedPojoToCache(rootOid, pojo);
+ adapter = objectAdapterContext.addRecreatedPojoToCache(rootOid, pojo);
adapterByOid.put(rootOid, adapter);
} catch(ObjectNotFoundException ex) {
throw ex; // just rethrow
@@ -1337,7 +1202,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
*/
@Override
public ObjectAdapter adapterFor(final RootOid rootOid) {
- return adapterFor(rootOid, ConcurrencyChecking.NO_CHECK);
+ return adapterFor(rootOid, AdapterManager.ConcurrencyChecking.NO_CHECK);
}
@@ -1371,10 +1236,10 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
@Override
public ObjectAdapter adapterFor(
final RootOid rootOid,
- final ConcurrencyChecking concurrencyChecking) {
+ final AdapterManager.ConcurrencyChecking concurrencyChecking) {
// attempt to locate adapter for the Oid
- ObjectAdapter adapter = lookupAdapterFor(rootOid);
+ ObjectAdapter adapter = objectAdapterContext.lookupAdapterFor(rootOid);
if (adapter == null) {
// else recreate
try {
@@ -1384,7 +1249,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
} else {
pojo = loadPersistentPojo(rootOid);
}
- adapter = addRecreatedPojoToCache(rootOid, pojo);
+ adapter = objectAdapterContext.addRecreatedPojoToCache(rootOid, pojo);
} catch(ObjectNotFoundException ex) {
throw ex; // just rethrow
} catch(RuntimeException ex) {
@@ -1401,7 +1266,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
private void sync(
- final ConcurrencyChecking concurrencyChecking,
+ final AdapterManager.ConcurrencyChecking concurrencyChecking,
final ObjectAdapter adapter, final RootOid rootOid) {
// sync versions of original, with concurrency checking if required
Oid adapterOid = adapter.getOid();
@@ -1419,7 +1284,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
otherVersion != null &&
thisVersion.different(otherVersion)) {
- if(concurrencyCheckingGloballyEnabled && ConcurrencyChecking.isCurrentlyEnabled()) {
+ if(concurrencyCheckingGloballyEnabled && AdapterManager.ConcurrencyChecking.isCurrentlyEnabled()) {
LOG.info("concurrency conflict detected on {} ({})", recreatedOid, otherVersion);
final String currentUser = authenticationSession.getUserName();
throw new ConcurrencyException(currentUser, recreatedOid, thisVersion, otherVersion);
@@ -1461,160 +1326,14 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
return pojo;
}
- @Override
- public ObjectAdapter adapterFor(final Object pojo) {
-
- if(pojo == null) {
- return null;
- }
- final ObjectAdapter existingOrValueAdapter = existingOrValueAdapter(pojo);
- if(existingOrValueAdapter != null) {
- return existingOrValueAdapter;
- }
-
- // Creates a new transient root {@link ObjectAdapter adapter} for the supplied domain
- final RootOid rootOid = createTransientOrViewModelOid(pojo);
- final ObjectAdapter newAdapter = objectAdapterContext.getFactories().createRootAdapter(pojo, rootOid);
-
- return mapAndInjectServices(newAdapter);
- }
-
- @Override
- public ObjectAdapter adapterFor(final Object pojo, final ObjectAdapter parentAdapter, final OneToManyAssociation collection) {
-
- assert parentAdapter != null;
- assert collection != null;
-
- final ObjectAdapter existingOrValueAdapter = existingOrValueAdapter(pojo);
- if(existingOrValueAdapter != null) {
- return existingOrValueAdapter;
- }
-
- ensureMapsConsistent(parentAdapter);
-
- // the List, Set etc. instance gets wrapped in its own adapter
- final ObjectAdapter newAdapter = objectAdapterContext.getFactories()
- .createCollectionAdapter(pojo, parentAdapter, collection);
-
- return mapAndInjectServices(newAdapter);
- }
-
-
-
- /**
- * Either returns an existing {@link ObjectAdapter adapter} (as per
- * {@link #lookupAdapterFor(Object)} or {@link #lookupAdapterFor(Oid)}), otherwise
- * re-creates an adapter with the specified (persistent) {@link Oid}.
- *
- * <p>
- * Typically called when the {@link Oid} is already known, that is, when
- * resolving an already-persisted object. Is also available for
- * <tt>Memento</tt> support however, so {@link Oid} could also represent a
- * {@link Oid#isTransient() transient} object.
- *
- * @param oid
- * @param recreatedPojo - already known to the object store impl, or a service
- */
- @Override
- public ObjectAdapter addRecreatedPojoToCache(final Oid oid, final Object recreatedPojo) {
-
- // attempt to locate adapter for the pojo
- // REVIEW: this check is possibly redundant because the pojo will most likely
- // have just been instantiated, so won't yet be in any maps
- final ObjectAdapter adapterLookedUpByPojo = lookupAdapterFor(recreatedPojo);
- if (adapterLookedUpByPojo != null) {
- return adapterLookedUpByPojo;
- }
-
- // attempt to locate adapter for the Oid
- final ObjectAdapter adapterLookedUpByOid = lookupAdapterFor(oid);
- if (adapterLookedUpByOid != null) {
- return adapterLookedUpByOid;
- }
-
- final ObjectAdapter createdAdapter = createRootOrAggregatedAdapter(oid, recreatedPojo);
- return mapAndInjectServices(createdAdapter);
- }
-
- /**
- * Removes the specified object from both the identity-adapter map, and the
- * pojo-adapter map.
- *
- * <p>
- * This indicates that the object is no longer in use, and therefore that no
- * objects exists within the system.
- *
- * <p>
- * If an {@link ObjectAdapter adapter} is removed while its pojo still is
- * referenced then a subsequent interaction of that pojo will create a
- * different {@link ObjectAdapter adapter}.
- *
- * <p>
- * TODO: should do a cascade remove of any aggregated objects.
- */
- @Override
- public void removeAdapterFromCache(final ObjectAdapter adapter) {
- ensureMapsConsistent(adapter);
- objectAdapterContext.removeAdapter(adapter);
- }
-
-
/**
* @deprecated https://issues.apache.org/jira/browse/ISIS-1976
*/
@Deprecated
private void remapRecreatedPojo(ObjectAdapter adapter, final Object pojo) {
- removeAdapterFromCache(adapter);
+ objectAdapterContext.removeAdapterFromCache(adapter);
adapter.replacePojo(pojo);
- mapAndInjectServices(adapter);
- }
-
-
- private ObjectAdapter createRootOrAggregatedAdapter(final Oid oid, final Object pojo) {
- final ObjectAdapter createdAdapter;
- if(oid instanceof RootOid) {
- final RootOid rootOid = (RootOid) oid;
- createdAdapter = objectAdapterContext.getFactories().createRootAdapter(pojo, rootOid);
- } else /*if (oid instanceof CollectionOid)*/ {
- final ParentedCollectionOid collectionOid = (ParentedCollectionOid) oid;
- createdAdapter = objectAdapterContext.getFactories().createCollectionAdapter(pojo, collectionOid);
- }
- return createdAdapter;
- }
-
-
-
- private ObjectAdapter mapAndInjectServices(final ObjectAdapter adapter) {
- // since the whole point of this method is to map an adapter that's just been created.
- // so we *don't* call ensureMapsConsistent(adapter);
-
- Assert.assertNotNull(adapter);
- final Object pojo = adapter.getObject();
- Assert.assertFalse("POJO Map already contains object", pojo, objectAdapterContext.containsAdapterForPojo(pojo));
-
- if (LOG.isDebugEnabled()) {
- // don't interact with the underlying object because may be a ghost
- // and would trigger a resolve
- // don't call toString() on adapter because calls hashCode on
- // underlying object, may also trigger a resolve.
- LOG.debug("adding identity for adapter with oid={}", adapter.getOid());
- }
-
- // value adapters are not mapped (but all others - root and aggregated adapters - are)
- if (adapter.isValue()) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("not mapping value adapter");
- }
- servicesInjector.injectServicesInto(pojo);
- return adapter;
- }
-
- objectAdapterContext.addAdapterHonoringSpecImmutability(pojo, adapter);
-
- // must inject after mapping, otherwise infinite loop
- servicesInjector.injectServicesInto(pojo);
-
- return adapter;
+ objectAdapterContext.mapAndInjectServices(adapter);
}
// -- TransactionManager delegate methods
@@ -1622,7 +1341,6 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
return transactionManager.getCurrentTransaction();
}
-
// -- FrameworkSynchronizer delegate methods
@Override
@@ -1636,7 +1354,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
}
@Override
- public void initializeMapAndCheckConcurrency(final Persistable pojo) {
+ public ObjectAdapter initializeMapAndCheckConcurrency(final Persistable pojo) {
final Persistable pc = pojo;
// need to do eagerly, because (if a viewModel then) a
@@ -1646,7 +1364,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
final Version datastoreVersion = getVersionIfAny(pc);
final RootOid originalOid;
- ObjectAdapter adapter = lookupAdapterFor(pojo);
+ ObjectAdapter adapter = objectAdapterContext.lookupAdapterFor(pojo);
if (adapter != null) {
ensureRootObject(pojo);
originalOid = (RootOid) adapter.getOid();
@@ -1666,7 +1384,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
otherVersion != null &&
thisVersion.different(otherVersion)) {
- if (ConcurrencyChecking.isCurrentlyEnabled()) {
+ if (AdapterManager.ConcurrencyChecking.isCurrentlyEnabled()) {
LOG.info("concurrency conflict detected on {} ({})", thisOid, otherVersion);
final String currentUser = authenticationSession.getUserName();
final ConcurrencyException abortCause = new ConcurrencyException(currentUser, thisOid,
@@ -1682,11 +1400,11 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
// it appears to be possible that there is already an adapter for this Oid,
// ie from ObjectStore#resolveImmediately()
- adapter = lookupAdapterFor(originalOid);
+ adapter = objectAdapterContext.lookupAdapterFor(originalOid);
if (adapter != null) {
remapRecreatedPojo(adapter, pojo);
} else {
- adapter = addRecreatedPojoToCache(originalOid, pojo);
+ adapter = objectAdapterContext.addRecreatedPojoToCache(originalOid, pojo);
CallbackFacet.Util.callCallback(adapter, LoadedCallbackFacet.class);
postLifecycleEventIfRequired(adapter, LoadedLifecycleEventFacet.class);
@@ -1694,6 +1412,8 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
}
adapter.setVersion(datastoreVersion);
+
+ return objectAdapterContext.lookupAdapterFor(pojo);
}
// -- create...Oid (main API)
@@ -1701,7 +1421,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
* Create a new {@link Oid#isTransient() transient} {@link Oid} for the
* supplied pojo, uniquely distinguishable from any other {@link Oid}.
*/
- private final RootOid createTransientOrViewModelOid(final Object pojo) {
+ final RootOid createTransientOrViewModelOid(final Object pojo) {
return newIdentifier(pojo, Type.TRANSIENT);
}
@@ -1770,7 +1490,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
*/
@Override
public void invokeIsisPersistingCallback(final Persistable pojo) {
- final ObjectAdapter adapter = lookupAdapterFor(pojo);
+ final ObjectAdapter adapter = objectAdapterContext.lookupAdapterFor(pojo);
if (adapter == null) {
// not expected.
return;
@@ -1831,7 +1551,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
@Override
public void enlistUpdatingAndInvokeIsisUpdatingCallback(final Persistable pojo) {
- ObjectAdapter adapter = lookupAdapterFor(pojo);
+ ObjectAdapter adapter = objectAdapterContext.lookupAdapterFor(pojo);
if (adapter == null) {
// seen this happen in the case when a parent entity (LeaseItem) has a collection of children
// objects (LeaseTerm) for which we haven't had a loaded callback fired and so are not yet
@@ -1888,9 +1608,6 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
return Utils.getVersionIfAny(pojo, authenticationSession);
}
-
-
-
// -- DomainObjectServices impl
@Override
@@ -1962,6 +1679,18 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
public ObjectAdapter adapterForViewModel(Object viewModelPojo, Function<ObjectSpecId, RootOid> rootOidFactory) {
return objectAdapterContext.adapterForViewModel(viewModelPojo, rootOidFactory);
}
+
+ @Override
+ public MementoRecreateObjectSupport mementoSupport() {
+ return objectAdapterContext.mementoSupport();
+ }
+
+ @Override
+ public ObjectAdapterProvider getObjectAdapterProvider() {
+ return objectAdapterProviderMixin;
+ }
+
+
}
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5_ObjectAdapterProvider.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5_ObjectAdapterProvider.java
new file mode 100644
index 0000000..5c8b85d
--- /dev/null
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5_ObjectAdapterProvider.java
@@ -0,0 +1,140 @@
+/*
+ * 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.runtime.system.persistence;
+
+import java.util.function.Function;
+
+import org.datanucleus.enhancement.Persistable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.runtime.system.persistence.adaptermanager.ObjectAdapterContext;
+
+public class PersistenceSession5_ObjectAdapterProvider implements ObjectAdapterProvider {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PersistenceSession5_ObjectAdapterProvider.class);
+
+ protected final PersistenceSession5 holder;
+ protected final ObjectAdapterContext objectAdapterContext;
+
+ // -- open
+
+ PersistenceSession5_ObjectAdapterProvider(PersistenceSession5 holder, ObjectAdapterContext objectAdapterContext) {
+ this.holder = holder;
+ this.objectAdapterContext = objectAdapterContext;
+ }
+
+ @Override
+ public ObjectAdapter adapterFor(Object pojo) {
+ //return holder.getObjectAdapterProvider().adapterFor(pojo);
+
+ if(pojo == null) {
+ return null;
+ }
+ final ObjectAdapter existingOrValueAdapter = existingOrValueAdapter(pojo);
+ if(existingOrValueAdapter != null) {
+ return existingOrValueAdapter;
+ }
+
+ // Creates a new transient root {@link ObjectAdapter adapter} for the supplied domain
+ final RootOid rootOid = holder.createTransientOrViewModelOid(pojo);
+ final ObjectAdapter newAdapter = objectAdapterContext.getFactories().createRootAdapter(pojo, rootOid);
+
+ return objectAdapterContext.mapAndInjectServices(newAdapter);
+ }
+
+ @Override
+ public ObjectAdapter adapterFor(Object pojo, ObjectAdapter parentAdapter, OneToManyAssociation collection) {
+ //return holder.getObjectAdapterProvider().adapterFor(pojo, parentAdapter, collection);
+
+ assert parentAdapter != null;
+ assert collection != null;
+
+ final ObjectAdapter existingOrValueAdapter = existingOrValueAdapter(pojo);
+ if(existingOrValueAdapter != null) {
+ return existingOrValueAdapter;
+ }
+
+ objectAdapterContext.ensureMapsConsistent(parentAdapter);
+
+ // the List, Set etc. instance gets wrapped in its own adapter
+ final ObjectAdapter newAdapter = objectAdapterContext.getFactories()
+ .createCollectionAdapter(pojo, parentAdapter, collection);
+
+ return objectAdapterContext.mapAndInjectServices(newAdapter);
+ }
+
+ @Override
+ public ObjectSpecification specificationForViewModel(Object viewModelPojo) {
+ return objectAdapterContext.specificationForViewModel(viewModelPojo);
+ }
+
+ @Override
+ public ObjectAdapter adapterForViewModel(Object viewModelPojo, Function<ObjectSpecId, RootOid> rootOidFactory) {
+ return objectAdapterContext.adapterForViewModel(viewModelPojo, rootOidFactory);
+ }
+
+ // -- HELPER
+
+ protected ObjectAdapter existingOrValueAdapter(Object pojo) {
+
+ // attempt to locate adapter for the pojo
+ ObjectAdapter adapter = objectAdapterContext.lookupAdapterByPojo(pojo);
+ if (adapter != null) {
+ return adapter;
+ }
+
+ // pojo may have been lazily loaded by object store, but we haven't yet seen it
+ if (pojo instanceof Persistable) {
+ adapter = holder.mapPersistent((Persistable) pojo);
+
+ // TODO: could return null if the pojo passed in !dnIsPersistent() || !dnIsDetached()
+ // in which case, we would ought to map as a transient object, rather than fall through and treat as a value?
+ } else {
+ adapter = null;
+ }
+
+ if(adapter != null) {
+ return adapter;
+ }
+
+ // need to create (and possibly map) the adapter.
+ final ObjectSpecification objSpec = holder.specificationLoader.loadSpecification(pojo.getClass());
+
+ // we create value facets as standalone (so not added to maps)
+ if (objSpec.containsFacet(ValueFacet.class)) {
+ adapter = objectAdapterContext.getFactories().createStandaloneAdapter(pojo);
+ return adapter;
+ }
+
+ return null;
+ }
+
+
+}
+
+
+
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryProcessorAbstract.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryProcessorAbstract.java
index d972273..def59fd 100644
--- a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryProcessorAbstract.java
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryProcessorAbstract.java
@@ -55,8 +55,7 @@ implements PersistenceQueryProcessor<T> {
ObjectAdapter adapter;
if(pojo instanceof Persistable) {
// an entity
- persistenceSession.initializeMapAndCheckConcurrency((Persistable) pojo);
- adapter = persistenceSession.lookupAdapterFor(pojo);
+ adapter = persistenceSession.initializeMapAndCheckConcurrency((Persistable) pojo);
} else {
// a value type
adapter = persistenceSession.adapterFor(pojo);
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/Memento.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/Memento.java
index 9e1eedc..57d566e 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/Memento.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/Memento.java
@@ -195,7 +195,8 @@ public class Memento implements Serializable {
final Oid oid = getOid();
- return ObjectAdapterLegacy.__Memento.recreateObject(spec, oid, data);
+ return getPersistenceSession().mementoSupport().recreateObject(spec, oid, data);
+
}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
index 4caa08d..aade4e5 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
@@ -18,6 +18,7 @@ package org.apache.isis.core.runtime.system.persistence;
import java.util.List;
import java.util.Map;
+import java.util.function.Function;
import javax.jdo.PersistenceManager;
@@ -32,13 +33,16 @@ import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
import org.apache.isis.core.metamodel.adapter.oid.ParentedCollectionOid;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
import org.apache.isis.core.metamodel.services.ServicesInjector;
+import org.apache.isis.core.metamodel.spec.ObjectSpecId;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
import org.apache.isis.core.runtime.persistence.objectstore.transaction.PersistenceCommand;
import org.apache.isis.core.runtime.persistence.objectstore.transaction.TransactionalResource;
import org.apache.isis.core.runtime.runner.opts.OptionHandlerFixtureAbstract;
+import org.apache.isis.core.runtime.system.persistence.adaptermanager.ObjectAdapterContext.MementoRecreateObjectSupport;
import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
-public interface PersistenceSession extends AdapterManager, TransactionalResource, SessionScopedComponent {
+public interface PersistenceSession extends ObjectAdapterProvider, TransactionalResource, SessionScopedComponent {
// -- CONSTANTS
@@ -59,21 +63,38 @@ public interface PersistenceSession extends AdapterManager, TransactionalResourc
public static final String DATANUCLEUS_PROPERTIES_ROOT = ROOT_KEY + "impl.";
- // -- INTERFACE DECLARATION
+ // -- OBJECT ADAPTER PROVIDER
- default ObjectAdapterProvider getObjectAdapterProvider() {
- return this;
+ ObjectAdapterProvider getObjectAdapterProvider();
+ default ObjectAdapter adapterFor(Object domainObject) {
+ return getObjectAdapterProvider().adapterFor(domainObject);
+ }
+ default ObjectAdapter adapterFor(
+ final Object pojo,
+ final ObjectAdapter parentAdapter,
+ OneToManyAssociation collection) {
+ return getObjectAdapterProvider().adapterFor(pojo, parentAdapter, collection);
+ }
+ default ObjectSpecification specificationForViewModel(final Object viewModelPojo) {
+ return getObjectAdapterProvider().specificationForViewModel(viewModelPojo);
+ }
+ default ObjectAdapter adapterForViewModel(
+ final Object viewModelPojo,
+ final Function<ObjectSpecId, RootOid> rootOidFactory) {
+ return getObjectAdapterProvider().adapterForViewModel(viewModelPojo, rootOidFactory);
}
+ //---
+
+ MementoRecreateObjectSupport mementoSupport();
+
ObjectAdapter adapterFor(RootOid rootOid);
-
- ObjectAdapter adapterFor(RootOid oid, ConcurrencyChecking concurrencyChecking);
-
+ ObjectAdapter adapterFor(RootOid oid, AdapterManager.ConcurrencyChecking concurrencyChecking);
ObjectAdapter adapterForAny(RootOid rootOid);
-
Map<RootOid, ObjectAdapter> adaptersFor(List<RootOid> rootOids);
-
<T> List<ObjectAdapter> allMatchingQuery(final Query<T> query);
+
+ // --
void close();
@@ -155,5 +176,4 @@ public interface PersistenceSession extends AdapterManager, TransactionalResourc
boolean isRepresentingPersistent(Object pojo);
boolean isDestroyed(Object pojo);
-
}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
index c3cdc1d..29855e3 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
@@ -27,7 +27,6 @@ import org.slf4j.LoggerFactory;
import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.commons.ensure.IsisAssertException;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
import org.apache.isis.core.metamodel.adapter.oid.Oid;
import org.apache.isis.core.metamodel.adapter.oid.ParentedCollectionOid;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
@@ -39,6 +38,7 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecId;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
+import org.apache.isis.core.runtime.memento.Data;
import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
/**
@@ -51,9 +51,12 @@ public class ObjectAdapterContext {
private final PojoAdapterHashMap pojoAdapterMap = new PojoAdapterHashMap();
private final OidAdapterHashMap oidAdapterMap = new OidAdapterHashMap();
- private final AdapterManager adapterManager; //FIXME[ISIS-1976] remove
+ private final PersistenceSession persistenceSession;
private final ServicesInjector servicesInjector;
private final SpecificationLoader specificationLoader;
+ private final ObjectAdapterContext_Consistency consistencyMixin;
+ private final ObjectAdapterContext_AdapterManager adapterManagerMixin;
+ private final ObjectAdapterContext_MementoSupport mementoSupportMixin;
ObjectAdapterContext(
ServicesInjector servicesInjector,
@@ -61,7 +64,11 @@ public class ObjectAdapterContext {
SpecificationLoader specificationLoader,
PersistenceSession persistenceSession) {
- this.adapterManager = persistenceSession;
+ this.consistencyMixin = new ObjectAdapterContext_Consistency(this);
+ this.adapterManagerMixin = new ObjectAdapterContext_AdapterManager(this, persistenceSession);
+ this.mementoSupportMixin = new ObjectAdapterContext_MementoSupport(this, persistenceSession);
+
+ this.persistenceSession = persistenceSession;
this.servicesInjector = servicesInjector;
this.specificationLoader = specificationLoader;
@@ -137,6 +144,16 @@ public class ObjectAdapterContext {
pojoAdapterMap.remove(adapter);
}
+ // -- CACHE CONSISTENCY
+
+ public void ensureMapsConsistent(final ObjectAdapter adapter) {
+ consistencyMixin.ensureMapsConsistent(adapter);
+ }
+
+ public void ensureMapsConsistent(final Oid oid) {
+ consistencyMixin.ensureMapsConsistent(oid);
+ }
+
// -- FACTORIES
public static interface ObjectAdapterFactories {
@@ -187,6 +204,38 @@ public class ObjectAdapterContext {
return objectAdapterFactories;
}
+ // -- ADAPTER MANAGER LEGACY
+
+ public ObjectAdapter addRecreatedPojoToCache(Oid oid, Object recreatedPojo) {
+ return adapterManagerMixin.addRecreatedPojoToCache(oid, recreatedPojo);
+ }
+
+ public ObjectAdapter mapAndInjectServices(final ObjectAdapter adapter) {
+ return adapterManagerMixin.mapAndInjectServices(adapter);
+ }
+
+ public ObjectAdapter lookupAdapterFor(Object pojo) {
+ return adapterManagerMixin.lookupAdapterFor(pojo);
+ }
+
+ public ObjectAdapter lookupAdapterFor(final Oid oid) {
+ return adapterManagerMixin.lookupAdapterFor(oid);
+ }
+
+ public void removeAdapterFromCache(final ObjectAdapter adapter) {
+ adapterManagerMixin.removeAdapterFromCache(adapter);
+ }
+
+ // -- MEMENTO SUPPORT
+
+ public static interface MementoRecreateObjectSupport {
+ ObjectAdapter recreateObject(ObjectSpecification spec, Oid oid, Data data);
+ }
+
+ public MementoRecreateObjectSupport mementoSupport() {
+ return mementoSupportMixin;
+ }
+
// ------------------------------------------------------------------------------------------------
@Deprecated // don't expose caching
@@ -218,20 +267,20 @@ public class ObjectAdapterContext {
final ObjectSpecification spec = viewModelAdapter.getSpecification();
if(createdTemporaryAdapter[0]) {
- adapterManager.removeAdapterFromCache(viewModelAdapter);
+ adapterManagerMixin.removeAdapterFromCache(viewModelAdapter);
}
return spec;
}
public ObjectAdapter adapterForViewModel(Object viewModelPojo, Function<ObjectSpecId, RootOid> rootOidFactory) {
- ObjectAdapter viewModelAdapter = adapterManager.lookupAdapterFor(viewModelPojo);
+ ObjectAdapter viewModelAdapter = adapterManagerMixin.lookupAdapterFor(viewModelPojo);
if(viewModelAdapter == null) {
final ObjectSpecification objectSpecification =
specificationLoader.loadSpecification(viewModelPojo.getClass());
final ObjectSpecId objectSpecId = objectSpecification.getSpecId();
final RootOid newRootOid = rootOidFactory.apply(objectSpecId);
- viewModelAdapter = adapterManager.addRecreatedPojoToCache(newRootOid, viewModelPojo);
+ viewModelAdapter = adapterManagerMixin.addRecreatedPojoToCache(newRootOid, viewModelPojo);
}
return viewModelAdapter;
}
@@ -252,7 +301,8 @@ public class ObjectAdapterContext {
final ObjectAdapter rootAdapter = adapter.getAggregateRoot(); // TODO: REVIEW: think this is redundant; would seem this method is only ever called for roots anyway.
final RootOid transientRootOid = (RootOid) rootAdapter.getOid();
- final RootAndCollectionAdapters rootAndCollectionAdapters = new RootAndCollectionAdapters(adapter, session);
+ final RootAndCollectionAdapters rootAndCollectionAdapters =
+ new RootAndCollectionAdapters(adapter, adapterManagerMixin);
removeFromCache(rootAndCollectionAdapters, transientRootOid);
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_AdapterManager.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_AdapterManager.java
new file mode 100644
index 0000000..25febc8
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_AdapterManager.java
@@ -0,0 +1,189 @@
+/*
+ * 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.runtime.system.persistence.adaptermanager;
+
+import java.util.Objects;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.core.commons.ensure.Assert;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+import org.apache.isis.core.metamodel.adapter.oid.ParentedCollectionOid;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.services.ServicesInjector;
+import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+
+/**
+ *
+ * @since 2.0.0-M2
+ */
+class ObjectAdapterContext_AdapterManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ObjectAdapterContext_AdapterManager.class);
+ private final ObjectAdapterContext objectAdapterContext;
+ private final PersistenceSession persistenceSession;
+ private final ServicesInjector servicesInjector;
+
+ ObjectAdapterContext_AdapterManager(ObjectAdapterContext objectAdapterContext,
+ PersistenceSession persistenceSession) {
+ this.objectAdapterContext = objectAdapterContext;
+ this.persistenceSession = persistenceSession;
+ this.servicesInjector = persistenceSession.getServicesInjector();
+ }
+
+ /**
+ * Either returns an existing {@link ObjectAdapter adapter} (as per
+ * {@link #lookupAdapterFor(Object)} or {@link #lookupAdapterFor(Oid)}), otherwise
+ * re-creates an adapter with the specified (persistent) {@link Oid}.
+ *
+ * <p>
+ * Typically called when the {@link Oid} is already known, that is, when
+ * resolving an already-persisted object. Is also available for
+ * <tt>Memento</tt> support however, so {@link Oid} could also represent a
+ * {@link Oid#isTransient() transient} object.
+ *
+ * @param oid
+ * @param recreatedPojo - already known to the object store impl, or a service
+ */
+ //@Override
+ public ObjectAdapter addRecreatedPojoToCache(Oid oid, Object recreatedPojo) {
+ // attempt to locate adapter for the pojo
+ // REVIEW: this check is possibly redundant because the pojo will most likely
+ // have just been instantiated, so won't yet be in any maps
+ final ObjectAdapter adapterLookedUpByPojo = lookupAdapterFor(recreatedPojo);
+ if (adapterLookedUpByPojo != null) {
+ return adapterLookedUpByPojo;
+ }
+
+ // attempt to locate adapter for the Oid
+ final ObjectAdapter adapterLookedUpByOid = lookupAdapterFor(oid);
+ if (adapterLookedUpByOid != null) {
+ return adapterLookedUpByOid;
+ }
+
+ final ObjectAdapter createdAdapter = createRootOrAggregatedAdapter(oid, recreatedPojo);
+ return mapAndInjectServices(createdAdapter);
+ }
+
+ /**
+ * Removes the specified object from both the identity-adapter map, and the
+ * pojo-adapter map.
+ *
+ * <p>
+ * This indicates that the object is no longer in use, and therefore that no
+ * objects exists within the system.
+ *
+ * <p>
+ * If an {@link ObjectAdapter adapter} is removed while its pojo still is
+ * referenced then a subsequent interaction of that pojo will create a
+ * different {@link ObjectAdapter adapter}.
+ *
+ * <p>
+ * TODO: should do a cascade remove of any aggregated objects.
+ */
+ //@Override
+ void removeAdapterFromCache(final ObjectAdapter adapter) {
+ objectAdapterContext.ensureMapsConsistent(adapter);
+ objectAdapterContext.removeAdapter(adapter);
+ }
+
+ /**
+ * Gets the {@link ObjectAdapter adapter} for the specified domain object if
+ * it exists in the identity map.
+ *
+ * <p>
+ * Provided by the <tt>AdapterManager</tt> when used by framework.
+ *
+ * @param pojo
+ * - must not be <tt>null</tt>
+ * @return adapter, or <tt>null</tt> if doesn't exist.
+ * @deprecated don't expose caching
+ */
+ //@Override
+ ObjectAdapter lookupAdapterFor(final Object pojo) {
+ Objects.requireNonNull(pojo);
+
+ return objectAdapterContext.lookupAdapterByPojo(pojo);
+ }
+
+ /**
+ * Gets the {@link ObjectAdapter adapter} for the {@link Oid} if it exists
+ * in the identity map.
+ *
+ * @param oid
+ * - must not be <tt>null</tt>
+ * @return adapter, or <tt>null</tt> if doesn't exist.
+ * @deprecated don't expose caching
+ */
+ //@Override
+ ObjectAdapter lookupAdapterFor(final Oid oid) {
+ Objects.requireNonNull(oid);
+ objectAdapterContext.ensureMapsConsistent(oid);
+
+ return objectAdapterContext.lookupAdapterById(oid);
+ }
+
+ ObjectAdapter mapAndInjectServices(final ObjectAdapter adapter) {
+ // since the whole point of this method is to map an adapter that's just been created.
+ // so we *don't* call ensureMapsConsistent(adapter);
+
+ Assert.assertNotNull(adapter);
+ final Object pojo = adapter.getObject();
+ Assert.assertFalse("POJO Map already contains object", pojo, objectAdapterContext.containsAdapterForPojo(pojo));
+
+ if (LOG.isDebugEnabled()) {
+ // don't interact with the underlying object because may be a ghost
+ // and would trigger a resolve
+ // don't call toString() on adapter because calls hashCode on
+ // underlying object, may also trigger a resolve.
+ LOG.debug("adding identity for adapter with oid={}", adapter.getOid());
+ }
+
+ // value adapters are not mapped (but all others - root and aggregated adapters - are)
+ if (adapter.isValue()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("not mapping value adapter");
+ }
+ servicesInjector.injectServicesInto(pojo);
+ return adapter;
+ }
+
+ objectAdapterContext.addAdapterHonoringSpecImmutability(pojo, adapter);
+
+ // must inject after mapping, otherwise infinite loop
+ servicesInjector.injectServicesInto(pojo);
+
+ return adapter;
+ }
+
+ ObjectAdapter createRootOrAggregatedAdapter(final Oid oid, final Object pojo) {
+ final ObjectAdapter createdAdapter;
+ if(oid instanceof RootOid) {
+ final RootOid rootOid = (RootOid) oid;
+ createdAdapter = objectAdapterContext.getFactories().createRootAdapter(pojo, rootOid);
+ } else /*if (oid instanceof CollectionOid)*/ {
+ final ParentedCollectionOid collectionOid = (ParentedCollectionOid) oid;
+ createdAdapter = objectAdapterContext.getFactories().createCollectionAdapter(pojo, collectionOid);
+ }
+ return createdAdapter;
+ }
+
+}
\ No newline at end of file
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_Consistency.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_Consistency.java
new file mode 100644
index 0000000..94b94d8
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_Consistency.java
@@ -0,0 +1,119 @@
+/*
+ * 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.runtime.system.persistence.adaptermanager;
+
+import static org.apache.isis.commons.internal.functions._Predicates.equalTo;
+import static org.apache.isis.core.commons.ensure.Ensure.ensureThatArg;
+
+import java.util.Objects;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+
+/**
+ *
+ * @since 2.0.0-M2
+ */
+class ObjectAdapterContext_Consistency {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ObjectAdapterContext_Consistency.class);
+ private final ObjectAdapterContext objectAdapterContext;
+
+ ObjectAdapterContext_Consistency(ObjectAdapterContext objectAdapterContext) {
+ this.objectAdapterContext = objectAdapterContext;
+ }
+
+ /**
+ * Fail early if any problems.
+ * @deprecated https://issues.apache.org/jira/browse/ISIS-1976
+ */
+ protected void ensureMapsConsistent(final ObjectAdapter adapter) {
+ if (adapter.isValue()) {
+ return;
+ }
+ if (adapter.isParentedCollection()) {
+ return;
+ }
+ ensurePojoAdapterMapConsistent(adapter);
+ ensureOidAdapterMapConsistent(adapter);
+ }
+
+ /**
+ * Fail early if any problems.
+ * @deprecated https://issues.apache.org/jira/browse/ISIS-1976
+ */
+ protected void ensureMapsConsistent(final Oid oid) {
+ Objects.requireNonNull(oid);
+
+ final ObjectAdapter adapter = objectAdapterContext.lookupAdapterById(oid);
+ if (adapter == null) {
+ return;
+ }
+ ensureOidAdapterMapConsistent(adapter);
+ ensurePojoAdapterMapConsistent(adapter);
+ }
+
+ private void ensurePojoAdapterMapConsistent(final ObjectAdapter adapter) {
+ final Object adapterPojo = adapter.getObject();
+ final ObjectAdapter adapterAccordingToMap = objectAdapterContext.lookupAdapterByPojo(adapterPojo);
+
+ if(adapterPojo == null) {
+ // nothing to check
+ return;
+ }
+ ensureMapConsistent(adapter, adapterAccordingToMap, "PojoAdapterMap");
+ }
+
+ private void ensureOidAdapterMapConsistent(final ObjectAdapter adapter) {
+ final Oid adapterOid = adapter.getOid();
+ final ObjectAdapter adapterAccordingToMap = objectAdapterContext.lookupAdapterById(adapterOid);
+
+ if(adapterOid == null) {
+ // nothing to check
+ return;
+ }
+ ensureMapConsistent(adapter, adapterAccordingToMap, "OidAdapterMap");
+ }
+
+ private void ensureMapConsistent(
+ final ObjectAdapter adapter,
+ final ObjectAdapter adapterAccordingToMap,
+ final String mapName) {
+
+ final Oid adapterOid = adapter.getOid();
+
+ // take care not to touch the pojo, since it might have been deleted.
+
+ if(adapterAccordingToMap == null) {
+ throw new IllegalStateException("mismatch in "
+ + mapName
+ + ": provided adapter's OID: " + adapterOid + "; but no adapter found in map");
+ }
+
+ ensureThatArg(
+ adapter, equalTo(adapterAccordingToMap),
+ ()->"mismatch in "
+ + mapName
+ + ": provided adapter's OID: " + adapterOid + ", \n"
+ + "but map's adapter's OID was: " + adapterAccordingToMap.getOid());
+ }
+}
\ No newline at end of file
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_MementoSupport.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_MementoSupport.java
new file mode 100644
index 0000000..d4a028d
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_MementoSupport.java
@@ -0,0 +1,246 @@
+/*
+ * 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.runtime.system.persistence.adaptermanager;
+
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.core.commons.ensure.Assert;
+import org.apache.isis.core.commons.exceptions.IsisException;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacetUtils;
+import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
+import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet;
+import org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySetterFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.core.runtime.memento.CollectionData;
+import org.apache.isis.core.runtime.memento.Data;
+import org.apache.isis.core.runtime.memento.ObjectData;
+import org.apache.isis.core.runtime.memento.StandaloneData;
+import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+import org.apache.isis.core.runtime.system.persistence.adaptermanager.ObjectAdapterContext.MementoRecreateObjectSupport;
+
+/**
+ *
+ * @since 2.0.0-M2
+ */
+class ObjectAdapterContext_MementoSupport implements MementoRecreateObjectSupport {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ObjectAdapterContext_MementoSupport.class);
+ private final ObjectAdapterContext objectAdapterContext;
+ private final PersistenceSession persistenceSession;
+
+ ObjectAdapterContext_MementoSupport(ObjectAdapterContext objectAdapterContext,
+ PersistenceSession persistenceSession) {
+ this.objectAdapterContext = objectAdapterContext;
+ this.persistenceSession = persistenceSession;
+ }
+
+ @Override
+ public ObjectAdapter recreateObject(ObjectSpecification spec, Oid oid, Data data) {
+ ObjectAdapter adapter;
+
+ if (spec.isParentedOrFreeCollection()) {
+
+ final Object recreatedPojo = persistenceSession.instantiateAndInjectServices(spec);
+ adapter = objectAdapterContext.addRecreatedPojoToCache(oid, recreatedPojo);
+ populateCollection(adapter, (CollectionData) data);
+
+ } else {
+ Assert.assertTrue("oid must be a RootOid representing an object because spec is not a collection and cannot be a value", oid instanceof RootOid);
+ RootOid typedOid = (RootOid) oid;
+
+ // remove adapter if already in the adapter manager maps, because
+ // otherwise would (as a side-effect) update the version to that of the current.
+ adapter = objectAdapterContext.lookupAdapterFor(typedOid);
+ if(adapter != null) {
+ objectAdapterContext.removeAdapterFromCache(adapter);
+ }
+
+ // recreate an adapter for the original OID (with correct version)
+ adapter = persistenceSession.adapterFor(typedOid);
+
+ updateObject(adapter, data);
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("recreated object {}", adapter.getOid());
+ }
+ return adapter;
+ }
+
+ private ObjectAdapter recreateReference(Data data) {
+ // handle values
+ if (data instanceof StandaloneData) {
+ final StandaloneData standaloneData = (StandaloneData) data;
+ return standaloneData.getAdapter();
+ }
+
+ // reference to entity
+
+ Oid oid = data.getOid();
+ Assert.assertTrue("can only create a reference to an entity", oid instanceof RootOid);
+
+ final RootOid rootOid = (RootOid) oid;
+ final ObjectAdapter referencedAdapter = persistenceSession.adapterFor(rootOid);
+
+ if (data instanceof ObjectData) {
+ if (rootOid.isTransient()) {
+ updateObject(referencedAdapter, data);
+ }
+ }
+ return referencedAdapter;
+ }
+
+ private void updateObject(final ObjectAdapter adapter, final Data data) {
+ final Object oid = adapter.getOid();
+ if (oid != null && !oid.equals(data.getOid())) {
+ throw new IllegalArgumentException("This memento can only be used to update the ObjectAdapter with the Oid " + data.getOid() + " but is " + oid);
+ }
+ if (!(data instanceof ObjectData)) {
+ throw new IsisException("Expected an ObjectData but got " + data.getClass());
+ }
+
+ updateFieldsAndResolveState(adapter, data);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("object updated {}", adapter.getOid());
+ }
+ }
+
+ private void populateCollection(final ObjectAdapter collectionAdapter, final CollectionData state) {
+ final ObjectAdapter[] initData = new ObjectAdapter[state.getElements().length];
+ int i = 0;
+ for (final Data elementData : state.getElements()) {
+ initData[i++] = recreateReference(elementData);
+ }
+ final CollectionFacet facet = collectionAdapter.getSpecification().getFacet(CollectionFacet.class);
+ facet.init(collectionAdapter, initData);
+ }
+
+ private void updateFieldsAndResolveState(final ObjectAdapter objectAdapter, final Data data) {
+
+ boolean dataIsTransient = data.getOid().isTransient();
+
+ if (!dataIsTransient) {
+ updateFields(objectAdapter, data);
+ objectAdapter.getOid().setVersion(data.getOid().getVersion());
+ } else if (objectAdapter.isTransient() && dataIsTransient) {
+ updateFields(objectAdapter, data);
+
+ } else if (objectAdapter.isParentedCollection()) {
+ // this branch is kind-a wierd, I think it's to handle aggregated adapters.
+ updateFields(objectAdapter, data);
+
+ } else {
+ final ObjectData od = (ObjectData) data;
+ if (od.containsField()) {
+ throw new IsisException("Resolve state (for " + objectAdapter + ") inconsistent with fact that data exists for fields");
+ }
+ }
+ }
+
+ private void updateFields(final ObjectAdapter object, final Data state) {
+ final ObjectData od = (ObjectData) state;
+ final List<ObjectAssociation> fields = object.getSpecification().getAssociations(Contributed.EXCLUDED);
+ for (final ObjectAssociation field : fields) {
+ if (field.isNotPersisted()) {
+ if (field.isOneToManyAssociation()) {
+ continue;
+ }
+ if (field.containsFacet(PropertyOrCollectionAccessorFacet.class) && !field.containsFacet(PropertySetterFacet.class)) {
+ LOG.debug("ignoring not-settable field {}", field.getName());
+ continue;
+ }
+ }
+ updateField(object, od, field);
+ }
+ }
+
+ private void updateField(final ObjectAdapter objectAdapter, final ObjectData objectData, final ObjectAssociation objectAssoc) {
+ final Object fieldData = objectData.getEntry(objectAssoc.getId());
+
+ if (objectAssoc.isOneToManyAssociation()) {
+ updateOneToManyAssociation(objectAdapter, (OneToManyAssociation) objectAssoc, (CollectionData) fieldData);
+
+ } else if (objectAssoc.getSpecification().containsFacet(EncodableFacet.class)) {
+ final EncodableFacet facet = objectAssoc.getSpecification().getFacet(EncodableFacet.class);
+ final ObjectAdapter value = facet.fromEncodedString((String) fieldData);
+ ((OneToOneAssociation) objectAssoc).initAssociation(objectAdapter, value);
+
+ } else if (objectAssoc.isOneToOneAssociation()) {
+ updateOneToOneAssociation(objectAdapter, (OneToOneAssociation) objectAssoc, (Data) fieldData);
+ }
+ }
+
+ private void updateOneToManyAssociation(final ObjectAdapter objectAdapter, final OneToManyAssociation otma, final CollectionData collectionData) {
+ final ObjectAdapter collection = otma.get(objectAdapter, InteractionInitiatedBy.FRAMEWORK);
+ final CollectionFacet facet = CollectionFacetUtils.getCollectionFacetFromSpec(collection);
+ final List<ObjectAdapter> original = _Lists.newArrayList();
+ for (final ObjectAdapter adapter : facet.iterable(collection)) {
+ original.add(adapter);
+ }
+
+ final Data[] elements = collectionData.getElements();
+ for (final Data data : elements) {
+ final ObjectAdapter elementAdapter = recreateReference(data);
+ if (!facet.contains(collection, elementAdapter)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(" association {} changed, added {}", otma, elementAdapter.getOid());
+ }
+ otma.addElement(objectAdapter, elementAdapter, InteractionInitiatedBy.FRAMEWORK);
+ } else {
+ otma.removeElement(objectAdapter, elementAdapter, InteractionInitiatedBy.FRAMEWORK);
+ }
+ }
+
+ for (final ObjectAdapter element : original) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(" association {} changed, removed {}", otma, element.getOid());
+ }
+ otma.removeElement(objectAdapter, element, InteractionInitiatedBy.FRAMEWORK);
+ }
+ }
+
+ private void updateOneToOneAssociation(final ObjectAdapter objectAdapter, final OneToOneAssociation otoa, final Data assocData) {
+ if (assocData == null) {
+ otoa.initAssociation(objectAdapter, null);
+ } else {
+ final ObjectAdapter ref = recreateReference(assocData);
+ if (otoa.get(objectAdapter, InteractionInitiatedBy.FRAMEWORK) != ref) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(" association {} changed to {}", otoa, ref.getOid());
+ }
+ otoa.initAssociation(objectAdapter, ref);
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterLegacy.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterLegacy.java
index 2f01ffa..af9930f 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterLegacy.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterLegacy.java
@@ -26,31 +26,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.commons.internal.collections._Lists;
import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.commons.ensure.Assert;
-import org.apache.isis.core.commons.exceptions.IsisException;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.oid.Oid;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
-import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
-import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacetUtils;
-import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
-import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet;
-import org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySetterFacet;
import org.apache.isis.core.metamodel.services.ServicesInjector;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.feature.Contributed;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
-import org.apache.isis.core.runtime.memento.CollectionData;
-import org.apache.isis.core.runtime.memento.Data;
-import org.apache.isis.core.runtime.memento.ObjectData;
-import org.apache.isis.core.runtime.memento.StandaloneData;
import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
import org.apache.isis.schema.common.v1.CollectionDto;
@@ -129,197 +110,4 @@ public class ObjectAdapterLegacy {
}
- // -- Memento --------------------------------------------------------
-
- public static class __Memento {
-
- public static ObjectAdapter recreateObject(ObjectSpecification spec, Oid oid, Data data) {
- ObjectAdapter adapter;
-
- if (spec.isParentedOrFreeCollection()) {
-
- final Object recreatedPojo = getPersistenceSession().instantiateAndInjectServices(spec);
- adapter = getPersistenceSession().addRecreatedPojoToCache(oid, recreatedPojo);
- populateCollection(adapter, (CollectionData) data);
-
- } else {
- Assert.assertTrue("oid must be a RootOid representing an object because spec is not a collection and cannot be a value", oid instanceof RootOid);
- RootOid typedOid = (RootOid) oid;
-
- // remove adapter if already in the adapter manager maps, because
- // otherwise would (as a side-effect) update the version to that of the current.
- adapter = getPersistenceSession().lookupAdapterFor(typedOid);
- if(adapter != null) {
- getPersistenceSession().removeAdapterFromCache(adapter);
- }
-
- // recreate an adapter for the original OID (with correct version)
- adapter = getPersistenceSession().adapterFor(typedOid);
-
- ObjectAdapterLegacy.__Memento.updateObject(adapter, data);
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("recreated object {}", adapter.getOid());
- }
- return adapter;
- }
-
- private static ObjectAdapter recreateReference(Data data) {
- // handle values
- if (data instanceof StandaloneData) {
- final StandaloneData standaloneData = (StandaloneData) data;
- return standaloneData.getAdapter();
- }
-
- // reference to entity
-
- Oid oid = data.getOid();
- Assert.assertTrue("can only create a reference to an entity", oid instanceof RootOid);
-
- final RootOid rootOid = (RootOid) oid;
- final ObjectAdapter referencedAdapter = getPersistenceSession().adapterFor(rootOid);
-
- if (data instanceof ObjectData) {
- if (rootOid.isTransient()) {
- updateObject(referencedAdapter, data);
- }
- }
- return referencedAdapter;
- }
-
- private static void updateObject(final ObjectAdapter adapter, final Data data) {
- final Object oid = adapter.getOid();
- if (oid != null && !oid.equals(data.getOid())) {
- throw new IllegalArgumentException("This memento can only be used to update the ObjectAdapter with the Oid " + data.getOid() + " but is " + oid);
- }
- if (!(data instanceof ObjectData)) {
- throw new IsisException("Expected an ObjectData but got " + data.getClass());
- }
-
- updateFieldsAndResolveState(adapter, data);
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("object updated {}", adapter.getOid());
- }
- }
-
- private static void populateCollection(final ObjectAdapter collectionAdapter, final CollectionData state) {
- final ObjectAdapter[] initData = new ObjectAdapter[state.getElements().length];
- int i = 0;
- for (final Data elementData : state.getElements()) {
- initData[i++] = recreateReference(elementData);
- }
- final CollectionFacet facet = collectionAdapter.getSpecification().getFacet(CollectionFacet.class);
- facet.init(collectionAdapter, initData);
- }
-
- private static void updateFieldsAndResolveState(final ObjectAdapter objectAdapter, final Data data) {
-
- boolean dataIsTransient = data.getOid().isTransient();
-
- if (!dataIsTransient) {
- updateFields(objectAdapter, data);
- objectAdapter.getOid().setVersion(data.getOid().getVersion());
- } else if (objectAdapter.isTransient() && dataIsTransient) {
- updateFields(objectAdapter, data);
-
- } else if (objectAdapter.isParentedCollection()) {
- // this branch is kind-a wierd, I think it's to handle aggregated adapters.
- updateFields(objectAdapter, data);
-
- } else {
- final ObjectData od = (ObjectData) data;
- if (od.containsField()) {
- throw new IsisException("Resolve state (for " + objectAdapter + ") inconsistent with fact that data exists for fields");
- }
- }
- }
-
- private static void updateFields(final ObjectAdapter object, final Data state) {
- final ObjectData od = (ObjectData) state;
- final List<ObjectAssociation> fields = object.getSpecification().getAssociations(Contributed.EXCLUDED);
- for (final ObjectAssociation field : fields) {
- if (field.isNotPersisted()) {
- if (field.isOneToManyAssociation()) {
- continue;
- }
- if (field.containsFacet(PropertyOrCollectionAccessorFacet.class) && !field.containsFacet(PropertySetterFacet.class)) {
- LOG.debug("ignoring not-settable field {}", field.getName());
- continue;
- }
- }
- updateField(object, od, field);
- }
- }
-
- private static void updateField(final ObjectAdapter objectAdapter, final ObjectData objectData, final ObjectAssociation objectAssoc) {
- final Object fieldData = objectData.getEntry(objectAssoc.getId());
-
- if (objectAssoc.isOneToManyAssociation()) {
- updateOneToManyAssociation(objectAdapter, (OneToManyAssociation) objectAssoc, (CollectionData) fieldData);
-
- } else if (objectAssoc.getSpecification().containsFacet(EncodableFacet.class)) {
- final EncodableFacet facet = objectAssoc.getSpecification().getFacet(EncodableFacet.class);
- final ObjectAdapter value = facet.fromEncodedString((String) fieldData);
- ((OneToOneAssociation) objectAssoc).initAssociation(objectAdapter, value);
-
- } else if (objectAssoc.isOneToOneAssociation()) {
- updateOneToOneAssociation(objectAdapter, (OneToOneAssociation) objectAssoc, (Data) fieldData);
- }
- }
-
- private static void updateOneToManyAssociation(final ObjectAdapter objectAdapter, final OneToManyAssociation otma, final CollectionData collectionData) {
- final ObjectAdapter collection = otma.get(objectAdapter, InteractionInitiatedBy.FRAMEWORK);
- final CollectionFacet facet = CollectionFacetUtils.getCollectionFacetFromSpec(collection);
- final List<ObjectAdapter> original = _Lists.newArrayList();
- for (final ObjectAdapter adapter : facet.iterable(collection)) {
- original.add(adapter);
- }
-
- final Data[] elements = collectionData.getElements();
- for (final Data data : elements) {
- final ObjectAdapter elementAdapter = recreateReference(data);
- if (!facet.contains(collection, elementAdapter)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug(" association {} changed, added {}", otma, elementAdapter.getOid());
- }
- otma.addElement(objectAdapter, elementAdapter, InteractionInitiatedBy.FRAMEWORK);
- } else {
- otma.removeElement(objectAdapter, elementAdapter, InteractionInitiatedBy.FRAMEWORK);
- }
- }
-
- for (final ObjectAdapter element : original) {
- if (LOG.isDebugEnabled()) {
- LOG.debug(" association {} changed, removed {}", otma, element.getOid());
- }
- otma.removeElement(objectAdapter, element, InteractionInitiatedBy.FRAMEWORK);
- }
- }
-
- private static void updateOneToOneAssociation(final ObjectAdapter objectAdapter, final OneToOneAssociation otoa, final Data assocData) {
- if (assocData == null) {
- otoa.initAssociation(objectAdapter, null);
- } else {
- final ObjectAdapter ref = recreateReference(assocData);
- if (otoa.get(objectAdapter, InteractionInitiatedBy.FRAMEWORK) != ref) {
- if (LOG.isDebugEnabled()) {
- LOG.debug(" association {} changed to {}", otoa, ref.getOid());
- }
- otoa.initAssociation(objectAdapter, ref);
- }
- }
- }
-
- private static PersistenceSession getPersistenceSession() {
- return IsisContext.getPersistenceSession().orElseThrow(_Exceptions::unexpectedCodeReach);
- }
-
-
-
- }
-
-
-
}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/RootAndCollectionAdapters.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/RootAndCollectionAdapters.java
index 5463820..f81a169 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/RootAndCollectionAdapters.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/RootAndCollectionAdapters.java
@@ -52,11 +52,11 @@ class RootAndCollectionAdapters implements Iterable<ObjectAdapter> {
public RootAndCollectionAdapters(
final ObjectAdapter parentAdapter,
- final AdapterManager adapterManager) {
+ final ObjectAdapterContext_AdapterManager adapterManagerMixin) {
Assert.assertNotNull(parentAdapter);
this.rootAdapterOid = (RootOid) parentAdapter.getOid();
this.parentAdapter = parentAdapter;
- addCollectionAdapters(adapterManager);
+ addCollectionAdapters(adapterManagerMixin);
}
public ObjectAdapter getRootAdapter() {
@@ -96,10 +96,10 @@ class RootAndCollectionAdapters implements Iterable<ObjectAdapter> {
// Helpers
////////////////////////////////////////////////////////////////////////
- private void addCollectionAdapters(AdapterManager objectAdapterLookup) {
+ private void addCollectionAdapters(ObjectAdapterContext_AdapterManager adapterManagerMixin) {
for (final OneToManyAssociation otma : parentAdapter.getSpecification().getCollections(Contributed.EXCLUDED)) {
final ParentedCollectionOid collectionOid = new ParentedCollectionOid((RootOid) rootAdapterOid, otma);
- final ObjectAdapter collectionAdapter = objectAdapterLookup.lookupAdapterFor(collectionOid);
+ final ObjectAdapter collectionAdapter = adapterManagerMixin.lookupAdapterFor(collectionOid);
if (collectionAdapter != null) {
// collection adapters are lazily created and so there may not be one.
addCollectionAdapter(otma, collectionAdapter);
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/ConverterForObjectAdapter.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/ConverterForObjectAdapter.java
index afd9e0f..a87b80d 100644
--- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/ConverterForObjectAdapter.java
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/ConverterForObjectAdapter.java
@@ -23,6 +23,7 @@ import java.util.Locale;
import org.apache.wicket.util.convert.IConverter;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.oid.Oid;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
@@ -44,8 +45,11 @@ public class ConverterForObjectAdapter implements IConverter<ObjectAdapter> {
*/
@Override
public ObjectAdapter convertToObject(final String value, final Locale locale) {
- final Oid oid = RootOid.deStringEncoded(value);
- return getPersistenceSession().lookupAdapterFor(oid);
+ final RootOid rootOid = RootOid.deStringEncoded(value);
+
+ //FIXME[ISIS-1976]
+ //return getPersistenceSession().lookupAdapterFor(rootOid);
+ throw _Exceptions.notImplemented();
}
/**
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/ConverterForObjectAdapterMemento.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/ConverterForObjectAdapterMemento.java
index 48db82b..ff3ce43 100644
--- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/ConverterForObjectAdapterMemento.java
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/ConverterForObjectAdapterMemento.java
@@ -25,6 +25,7 @@ import com.google.common.base.Strings;
import org.apache.wicket.util.convert.IConverter;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
import org.apache.isis.core.metamodel.adapter.oid.Oid;
@@ -54,8 +55,11 @@ public class ConverterForObjectAdapterMemento implements IConverter<ObjectAdapte
return null;
}
final Oid oid = RootOid.deStringEncoded(value);
- final ObjectAdapter adapter = getPersistenceSession().lookupAdapterFor(oid);
- return ObjectAdapterMemento.createOrNull(adapter);
+
+ //FIXME[ISIS-1976]
+ //final ObjectAdapter adapter = getPersistenceSession().lookupAdapterFor(oid);
+ //return ObjectAdapterMemento.createOrNull(adapter);
+ throw _Exceptions.notImplemented();
}
/**