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/06 16:12:47 UTC

[isis] branch ISIS-1976-rethink-object-adapters updated (9b304a3 -> 4b7850b)

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a change to branch ISIS-1976-rethink-object-adapters
in repository https://gitbox.apache.org/repos/asf/isis.git.


 discard 9b304a3  ISIS-1976: further cleaning up
 discard 2d01709  ISIS-1976: cleaning up
 discard e0594d0  ISIS-1976: lazy initialize OAs for services
 discard 67fd1ec  ISIS-1976: further simplify
 discard 2772581  ISIS-1976: simplify
 discard 234421b  ISIS-1976: remove code that seems for optimization
 discard 369ebf6  ISIS-1976: restore check consistency to also check adapter's object equality
 discard dd69b28  ISIS-1976: improve code readability
 discard d8341fe  ISIS-1976: make ObjectAdapter's oid immutable
 discard 5412e90  ISIS-1976: add layer of abstraction
 discard 5a8b180  ISIS-1976: improve the ObjectAdapterProvider interface (API)
 discard f51d47a  ISIS-1976: minor cleanup
 discard 5fc28eb  ISIS-1976: prepare removal of OA's lookup by pojo map
 discard 67d3c09  ISIS-1976: prepare removal of OA's replacePojo
 discard b83de86  ISIS-1976: let ObjectAdapterContext.replaceRootAdapter(ObjectAdapter, RootAndCollectionAdapters) no longer use OA's replacePojo
 discard 2491edc  ISIS-1976: let JavaCollectionFacet no longer change OA's pojo
 discard 2ebc19e  ISIS-1976: removing ObjectAdapter.replacePojo(Object pojo)
 discard 1d8dfcf  ISIS-1976: make ObjectAdapter.pojo final
     add 0ae1dca  ISIS-1934: fixes Action Confirmation Dialog does not escape menu boundaries
     new aa93d1e  ISIS-1976: make ObjectAdapter.pojo final
     new 1f5520f  ISIS-1976: removing ObjectAdapter.replacePojo(Object pojo)
     new afd1fb9  ISIS-1976: let JavaCollectionFacet no longer change OA's pojo
     new 63a89c8  ISIS-1976: let ObjectAdapterContext.replaceRootAdapter(ObjectAdapter, RootAndCollectionAdapters) no longer use OA's replacePojo
     new 543759a  ISIS-1976: prepare removal of OA's replacePojo
     new b3e78b7  ISIS-1976: prepare removal of OA's lookup by pojo map
     new 5dcbc9f  ISIS-1976: minor cleanup
     new 11aa135  ISIS-1976: improve the ObjectAdapterProvider interface (API)
     new 392687a  ISIS-1976: add layer of abstraction
     new b66c9ed  ISIS-1976: make ObjectAdapter's oid immutable
     new 30d9e29  ISIS-1976: improve code readability
     new a99c1cc  ISIS-1976: restore check consistency to also check adapter's object equality
     new 6bf096e  ISIS-1976: remove code that seems for optimization
     new 989333f  ISIS-1976: simplify
     new 9e286dc  ISIS-1976: further simplify
     new 9eacd3c  ISIS-1976: lazy initialize OAs for services
     new f343919  ISIS-1976: cleaning up
     new 4b7850b  ISIS-1976: further cleaning up

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (9b304a3)
            \
             N -- N -- N   refs/heads/ISIS-1976-rethink-object-adapters (4b7850b)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 18 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 core/pom.xml                                                            | 2 +-
 .../ui/components/actionmenu/serviceactions/ServiceActionUtil.java      | 2 +-
 .../ui/components/actionmenu/serviceactions/ServiceActionsPanel.html    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)


[isis] 07/18: ISIS-1976: minor cleanup

Posted by ah...@apache.org.
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 5dcbc9f5e92983a48bd65306767ddb19a7fa85f7
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Sep 5 18:54:49 2018 +0200

    ISIS-1976: minor cleanup
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../adaptermanager/ObjectAdapterContext.java       | 66 ++++++++++++----------
 1 file changed, 36 insertions(+), 30 deletions(-)

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 cc59c62..a9535a6 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
@@ -41,7 +41,6 @@ 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.persistence.adapter.PojoAdapter;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
 
 /**
@@ -110,29 +109,39 @@ public class ObjectAdapterContext {
             oidAdapterMap.close();
         } catch(final Throwable ex) {
             // ignore
-            ObjectAdapterLegacy.LOG.error("close: oidAdapterMap#close() failed; continuing to avoid memory leakage");
+            LOG.error("close: oidAdapterMap#close() failed; continuing to avoid memory leakage");
         }
 
         try {
             pojoAdapterMap.close();
         } catch(final Throwable ex) {
             // ignore
-            ObjectAdapterLegacy.LOG.error("close: pojoAdapterMap#close() failed; continuing to avoid memory leakage");
+            LOG.error("close: pojoAdapterMap#close() failed; continuing to avoid memory leakage");
         }
     }
     
     // -- CACHING
 
     @Deprecated // don't expose caching
-    public boolean containsAdapterForPojo(Object pojo) {
-        return pojoAdapterMap.containsPojo(pojo);
+    protected ObjectAdapter lookupAdapterByPojo(Object pojo) {
+        return pojoAdapterMap.getAdapter(pojo);
+    }
+    
+    private void putPojo(Object pojo, ObjectAdapter adapter) {
+        pojoAdapterMap.add(adapter.getObject(), adapter);
     }
     
+    private void removePojo(ObjectAdapter adapter) {
+        pojoAdapterMap.remove(adapter);
+    }
+    
+    // --
+    
     @Deprecated // don't expose caching
-    protected ObjectAdapter lookupAdapterByPojo(Object pojo) {
-        return pojoAdapterMap.getAdapter(pojo);
+    public boolean containsAdapterForPojo(Object pojo) {
+        return lookupAdapterByPojo(pojo)!=null;
     }
-
+    
     @Deprecated // don't expose caching
     protected ObjectAdapter lookupAdapterById(Oid oid) {
         return oidAdapterMap.getAdapter(oid);
@@ -147,7 +156,7 @@ public class ObjectAdapterContext {
         if (oid != null) { // eg. value objects don't have an Oid
             oidAdapterMap.add(oid, adapter);
         }
-        pojoAdapterMap.add(adapter.getObject(), adapter);
+        putPojo(adapter.getObject(), adapter);
     }
     
     @Deprecated // don't expose caching
@@ -160,7 +169,7 @@ public class ObjectAdapterContext {
         if (oid != null) { // eg. value objects don't have an Oid
             oidAdapterMap.remove(oid);
         }
-        pojoAdapterMap.remove(adapter);
+        removePojo(adapter);
     }
     
     // -- CACHE CONSISTENCY
@@ -299,7 +308,7 @@ public class ObjectAdapterContext {
         // add all aggregated collections
         final ObjectSpecification objSpec = adapter.getSpecification();
         if (!adapter.isParentedCollection() || adapter.isParentedCollection() && !objSpec.isImmutable()) {
-            pojoAdapterMap.add(pojo, adapter);
+            putPojo(pojo, adapter);
         }
 
         // order is important - add to pojo map first, then identity map
@@ -382,16 +391,16 @@ public class ObjectAdapterContext {
         }
 
         // associate root adapter with the new Oid, and remap
-        if (ObjectAdapterLegacy.LOG.isDebugEnabled()) {
-            ObjectAdapterLegacy.LOG.debug("replacing root adapter and re-adding into maps; oid is now: {} (was: {})", persistedRootOid.enString(), transientRootOid.enString());
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("replacing root adapter and re-adding into maps; oid is now: {} (was: {})", persistedRootOid.enString(), transientRootOid.enString());
         }
         
         final ObjectAdapter adapterReplacement = adapter.withOid(persistedRootOid); 
         
         replaceRootAdapter(adapterReplacement, rootAndCollectionAdapters);
         
-        if (ObjectAdapterLegacy.LOG.isDebugEnabled()) {
-            ObjectAdapterLegacy.LOG.debug("made persistent {}; was {}", adapterReplacement, transientRootOid);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("made persistent {}; was {}", adapterReplacement, transientRootOid);
         }
     }
 
@@ -403,11 +412,8 @@ public class ObjectAdapterContext {
         
         final RootOid persistedRootOid = (RootOid) adapterReplacement.getOid();
         
-//        oidAdapterMap.add(persistedRootOid, adapterReplacement);
-//        pojoAdapterMap.add(adapterReplacement.getObject(), adapterReplacement);
-
         // associate the collection adapters with new Oids, and re-map
-        ObjectAdapterLegacy.LOG.debug("replacing Oids for collection adapter(s) and re-adding into maps");
+        LOG.debug("replacing Oids for collection adapter(s) and re-adding into maps");
         
         for (final ObjectAdapter collectionAdapter : rootAndCollectionAdapters) {
             final ParentedCollectionOid previousCollectionOid = (ParentedCollectionOid) collectionAdapter.getOid();
@@ -417,8 +423,8 @@ public class ObjectAdapterContext {
 
         // some object store implementations may replace collection instances (eg ORM may replace with a cglib-enhanced
         // proxy equivalent.  So, ensure that the collection adapters still wrap the correct pojos.
-        if (ObjectAdapterLegacy.LOG.isDebugEnabled()) {
-            ObjectAdapterLegacy.LOG.debug("synchronizing collection pojos, remapping in pojo map if required");
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("synchronizing collection pojos, remapping in pojo map if required");
         }
         for (final OneToManyAssociation otma : rootAndCollectionAdapters.getCollections()) {
             final ObjectAdapter collectionAdapter = rootAndCollectionAdapters.getCollectionAdapter(otma);
@@ -427,9 +433,9 @@ public class ObjectAdapterContext {
             final Object collectionPojoActuallyOnPojo = getCollectionPojo(otma, adapterReplacement);
 
             if (collectionPojoActuallyOnPojo != collectionPojoWrappedByAdapter) {
-                pojoAdapterMap.remove(collectionAdapter);
+                removePojo(collectionAdapter);
                 final ObjectAdapter newCollectionAdapter = collectionAdapter.withPojo(collectionPojoActuallyOnPojo);
-                pojoAdapterMap.add(collectionPojoActuallyOnPojo, newCollectionAdapter);
+                putPojo(collectionPojoActuallyOnPojo, newCollectionAdapter);
             }
         }
         
@@ -438,17 +444,17 @@ public class ObjectAdapterContext {
     private void removeFromCache(
             final RootAndCollectionAdapters rootAndCollectionAdapters, 
             final RootOid transientRootOid) {
-        ObjectAdapterLegacy.LOG.debug("remapAsPersistent: {}", transientRootOid);
-        ObjectAdapterLegacy.LOG.debug("removing root adapter from oid map");
+        LOG.debug("remapAsPersistent: {}", transientRootOid);
+        LOG.debug("removing root adapter from oid map");
     
         boolean removed = oidAdapterMap.remove(transientRootOid);
         if (!removed) {
-            ObjectAdapterLegacy.LOG.warn("could not remove oid: {}", transientRootOid);
+            LOG.warn("could not remove oid: {}", transientRootOid);
             // should we fail here with a more serious error?
         }
     
-        if (ObjectAdapterLegacy.LOG.isDebugEnabled()) {
-            ObjectAdapterLegacy.LOG.debug("removing collection adapter(s) from oid map");
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("removing collection adapter(s) from oid map");
         }
         for (final ObjectAdapter collectionAdapter : rootAndCollectionAdapters) {
             final Oid collectionOid = collectionAdapter.getOid();
@@ -471,8 +477,8 @@ public class ObjectAdapterContext {
     @Deprecated
     public ObjectAdapter remapRecreatedPojo(ObjectAdapter adapter, final Object pojo) {
         final ObjectAdapter newAdapter = adapter.withPojo(pojo);
-        pojoAdapterMap.remove(adapter);
-        pojoAdapterMap.remove(newAdapter);
+        removePojo(adapter);
+        removePojo(newAdapter);
         
         oidAdapterMap.remove(adapter.getOid());
         oidAdapterMap.remove(newAdapter.getOid());


[isis] 09/18: ISIS-1976: add layer of abstraction

Posted by ah...@apache.org.
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 392687a4ac27f3bebf3ac08116901b154becfda6
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 6 06:04:41 2018 +0200

    ISIS-1976: add layer of abstraction
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../core/metamodel/services/ServicesInjector.java  |  39 +++--
 .../adaptermanager/ObjectAdapterContext.java       | 194 +++++++++++----------
 .../ObjectAdapterContext_AdapterManager.java       |   3 +-
 ...ObjectAdapterContext_ObjectAdapterProvider.java |  12 +-
 4 files changed, 140 insertions(+), 108 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
index f80535b..d293abc 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
@@ -23,11 +23,16 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
+import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.collections._Collections;
 import org.apache.isis.commons.internal.collections._Lists;
@@ -48,8 +53,6 @@ import org.apache.isis.core.metamodel.specloader.InjectorMethodEvaluatorDefault;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.core.runtime.authentication.AuthenticationManager;
 import org.apache.isis.core.runtime.authorization.AuthorizationManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * The repository of services, also able to inject into any object.
@@ -78,7 +81,7 @@ public class ServicesInjector implements ApplicationScopedComponent {
      * services that are assignable to the type.  It's possible that this is an empty list.
      */
     private final Map<Class<?>, List<Object>> servicesAssignableToType = _Maps.newHashMap();
-    private final Map<Class<?>, Object> serviceByConcreteType = _Maps.newHashMap();
+    private final _Lazy<Map<Class<?>, Object>> serviceByConcreteType = _Lazy.of(this::initServiceByConcreteType);
     private final Map<Class<?>, Method[]> methodsByClassCache = _Maps.newHashMap();
     private final Map<Class<?>, Field[]> fieldsByClassCache = _Maps.newHashMap();
 
@@ -143,18 +146,30 @@ public class ServicesInjector implements ApplicationScopedComponent {
         serviceByConcreteType.clear();
         autowire();
     }
+    
+    private Map<Class<?>, Object> initServiceByConcreteType(){
+        final Map<Class<?>, Object> map = _Maps.newHashMap();
+        for (Object service : services) {
+            final Class<?> concreteType = service.getClass();
+            map.put(concreteType, service);
+        }
+        return map;
+    }
 
     public boolean isRegisteredService(final Class<?> cls) {
-        // lazily construct cache
-        if(serviceByConcreteType.isEmpty()) {
-            for (Object service : services) {
-                final Class<?> concreteType = service.getClass();
-                serviceByConcreteType.put(concreteType, service);
-            }
-        }
-        return serviceByConcreteType.containsKey(cls);
+        return serviceByConcreteType.get().containsKey(cls);
     }
 
+    public boolean isRegisteredServiceInstance(final Object pojo) {
+        if(pojo==null) {
+            return false;
+        }
+        final Class<?> key = pojo.getClass();
+        final Object serviceInstance = serviceByConcreteType.get().get(key);
+        return Objects.equals(pojo, serviceInstance);
+    }
+    
+    
     public <T> void addFallbackIfRequired(final Class<T> serviceClass, final T serviceInstance) {
         if(!contains(services, serviceClass)) {
             // add to beginning;
@@ -206,7 +221,7 @@ public class ServicesInjector implements ApplicationScopedComponent {
     public List<Object> getRegisteredServices() {
         return Collections.unmodifiableList(services);
     }
-
+    
     // -- INJECT SERVICES INTO
 
     /**
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 5ebfe1f..06642b2 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
@@ -22,10 +22,14 @@ import java.util.List;
 import java.util.Objects;
 import java.util.UUID;
 import java.util.function.Function;
+import java.util.function.Supplier;
+
+import com.google.common.cache.Cache;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.commons.internal.functions._Predicates;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.ensure.Ensure;
@@ -44,7 +48,9 @@ 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.persistence.adapter.PojoAdapter;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+import org.apache.isis.core.runtime.threadpool.ThreadPoolSupport;
 
 /**
  * Encapsulate ObjectAdpater life-cycling.  
@@ -67,9 +73,76 @@ public class ObjectAdapterContext {
         return objectAdapterContext;
     }
     
-    private final PojoAdapterHashMap pojoAdapterMap = new PojoAdapterHashMap();
-    private final OidAdapterHashMap oidAdapterMap = new OidAdapterHashMap();
-    private final OidAdapterHashMap oidAdapterMap2 = new OidAdapterHashMap();
+    private final static class Cache {
+        private final PojoAdapterHashMap pojoAdapterMap = new PojoAdapterHashMap();
+        private final OidAdapterHashMap oidAdapterMap = new OidAdapterHashMap();
+        
+        public void open() {
+            oidAdapterMap.open();
+            pojoAdapterMap.open();
+        }
+        
+        public void close() {
+            
+            try {
+                oidAdapterMap.close();
+            } catch(final Throwable ex) {
+                // ignore
+                LOG.error("close: oidAdapterMap#close() failed; continuing to avoid memory leakage");
+            }
+
+            try {
+                pojoAdapterMap.close();
+            } catch(final Throwable ex) {
+                // ignore
+                LOG.error("close: pojoAdapterMap#close() failed; continuing to avoid memory leakage");
+            }
+        }
+        
+        private ObjectAdapter lookupAdapterByPojo(Object pojo) {
+            final ObjectAdapter adapter = pojoAdapterMap.getAdapter(pojo);
+            return adapter;
+        }
+        
+        private void putPojo(Object pojo, ObjectAdapter adapter) {
+            pojoAdapterMap.add(adapter.getObject(), adapter);
+        }
+        
+        private void removePojo(ObjectAdapter adapter) {
+            pojoAdapterMap.remove(adapter);
+        }
+        
+        private ObjectAdapter lookupAdapterById(Oid oid) {
+            return oidAdapterMap.getAdapter(oid);
+        }
+        
+        private void addAdapter(ObjectAdapter adapter) {
+            if(adapter==null) {
+                return; // nothing to do
+            }
+            final Oid oid = adapter.getOid();
+            if (oid != null) { // eg. value objects don't have an Oid
+                oidAdapterMap.add(oid, adapter);
+            }
+            putPojo(adapter.getObject(), adapter);
+        }
+        
+        private void removeAdapter(ObjectAdapter adapter) {
+            LOG.debug("removing adapter: {}", adapter);
+            if(adapter==null) {
+                return; // nothing to do
+            }
+            final Oid oid = adapter.getOid();
+            if (oid != null) { // eg. value objects don't have an Oid
+                oidAdapterMap.remove(oid);
+            }
+            removePojo(adapter);
+        }
+        
+    }
+    
+    private final Cache cache = new Cache();
+    
     private final PersistenceSession persistenceSession; 
     private final ServicesInjector servicesInjector;
     private final SpecificationLoader specificationLoader;
@@ -102,103 +175,47 @@ public class ObjectAdapterContext {
     // -- LIFE-CYCLING
     
     public void open() {
-        oidAdapterMap.open();
-        pojoAdapterMap.open();
-        oidAdapterMap2.open();
+        cache.open();
         initServices();
     }
     
     public void close() {
-        
-        try {
-            oidAdapterMap.close();
-            oidAdapterMap2.close();
-        } catch(final Throwable ex) {
-            // ignore
-            LOG.error("close: oidAdapterMap#close() failed; continuing to avoid memory leakage");
-        }
-
-        try {
-            pojoAdapterMap.close();
-        } catch(final Throwable ex) {
-            // ignore
-            LOG.error("close: pojoAdapterMap#close() failed; continuing to avoid memory leakage");
-        }
+        cache.close();
     }
     
-    // -- CACHING DEPR.
+    // -- CACHING POJO
 
     @Deprecated // don't expose caching
     protected ObjectAdapter lookupAdapterByPojo(Object pojo) {
-        final ObjectAdapter adapter = pojoAdapterMap.getAdapter(pojo);
-        if(adapter!=null) {
-            Oid y = adapter.getOid();
-            Objects.requireNonNull(y);
-            
-            Oid x = objectAdapterProviderMixin.oidFor(pojo);
-            Objects.requireNonNull(x);
-            
-            //FIXME[ISIS-1976] oids must match
-            //Ensure.ensureThatArg(x, _Predicates.equalTo(y), ()->String.format("x: %s\ny: %s", ""+x, ""+y));
-        }
-        return adapter;
-    }
-    
-    private void putPojo(Object pojo, ObjectAdapter adapter) {
-        
-        Oid x = objectAdapterProviderMixin.oidFor(pojo);
-        Oid y = adapter.getOid();
-        Objects.requireNonNull(y);
-        
-        //FIXME[ISIS-1976] oids must match
-        //Ensure.ensureThatArg(x, _Predicates.equalTo(y), ()->String.format("x: %s\ny: %s", ""+x, ""+y));
-        
-        oidAdapterMap2.add(adapter.getOid(), adapter);
-        pojoAdapterMap.add(adapter.getObject(), adapter);
+        return cache.lookupAdapterByPojo(pojo);
     }
     
-    private void removePojo(ObjectAdapter adapter) {
-        Oid y = adapter.getOid();
-        Objects.requireNonNull(y);
-        oidAdapterMap2.remove(y);
-        pojoAdapterMap.remove(adapter);
-    }
-    
-    // -- CACHING
-    
     @Deprecated // don't expose caching
     public boolean containsAdapterForPojo(Object pojo) {
         return lookupAdapterByPojo(pojo)!=null;
     }
     
+    // -- CACHING OID
+    
     @Deprecated // don't expose caching
     protected ObjectAdapter lookupAdapterById(Oid oid) {
-        return oidAdapterMap.getAdapter(oid);
+        return cache.lookupAdapterById(oid);
     }
+    
+    private OidAdapterHashMap oidAdapterMap() {
+        return cache.oidAdapterMap;
+    }
+    
+    // -- CACHING BOTH
 
     @Deprecated // don't expose caching
     public void addAdapter(ObjectAdapter adapter) {
-        if(adapter==null) {
-            return; // nothing to do
-        }
-        final Oid oid = adapter.getOid();
-        if (oid != null) { // eg. value objects don't have an Oid
-            oidAdapterMap.add(oid, adapter);
-        }
-        putPojo(adapter.getObject(), adapter);
+        cache.addAdapter(adapter);
     }
     
     @Deprecated // don't expose caching
     public void removeAdapter(ObjectAdapter adapter) {
-        LOG.debug("removing adapter: {}", adapter);
-        if(adapter==null) {
-            return; // nothing to do
-        }
-        final Oid oid = adapter.getOid();
-        if (oid != null) { // eg. value objects don't have an Oid
-            oidAdapterMap.remove(oid);
-        }
-        removePojo(adapter);
+        cache.removeAdapter(adapter);
     }
     
     // -- CACHE CONSISTENCY
@@ -327,7 +344,8 @@ public class ObjectAdapterContext {
             
             // remap as Persistent if required
             if (serviceAdapter.getOid().isTransient()) {
-                remapAsPersistent(serviceAdapter, null, persistenceSession);
+                _Exceptions.unexpectedCodeReach();
+                //remapAsPersistent(serviceAdapter, null, persistenceSession);
             }
         }
     }
@@ -337,11 +355,11 @@ public class ObjectAdapterContext {
         // add all aggregated collections
         final ObjectSpecification objSpec = adapter.getSpecification();
         if (!adapter.isParentedCollection() || adapter.isParentedCollection() && !objSpec.isImmutable()) {
-            putPojo(pojo, adapter);
+            cache.putPojo(pojo, adapter);
         }
 
         // order is important - add to pojo map first, then identity map
-        oidAdapterMap.add(adapter.getOid(), adapter);
+        oidAdapterMap().add(adapter.getOid(), adapter);
     }
     
     public ObjectAdapter disposableAdapterForViewModel(Object viewModelPojo) {
@@ -367,9 +385,6 @@ public class ObjectAdapterContext {
     }
     
     /**
-     * was in PersisenceSessionX, temporarily moved here to successfully compile
-     *
-     * <p>
      * Note that there is no management of {@link Version}s here. That is
      * because the {@link PersistenceSession} is expected to manage this.
      *
@@ -434,7 +449,7 @@ public class ObjectAdapterContext {
         for (final ObjectAdapter collectionAdapter : rootAndCollectionAdapters) {
             final ParentedCollectionOid previousCollectionOid = (ParentedCollectionOid) collectionAdapter.getOid();
             final ParentedCollectionOid persistedCollectionOid = previousCollectionOid.asPersistent(persistedRootOid);
-            oidAdapterMap.add(persistedCollectionOid, collectionAdapter);
+            oidAdapterMap().add(persistedCollectionOid, collectionAdapter);
         }
 
         // some object store implementations may replace collection instances (eg ORM may replace with a cglib-enhanced
@@ -449,9 +464,9 @@ public class ObjectAdapterContext {
             final Object collectionPojoActuallyOnPojo = getCollectionPojo(otma, adapterReplacement);
 
             if (collectionPojoActuallyOnPojo != collectionPojoWrappedByAdapter) {
-                removePojo(collectionAdapter);
+                cache.removePojo(collectionAdapter);
                 final ObjectAdapter newCollectionAdapter = collectionAdapter.withPojo(collectionPojoActuallyOnPojo);
-                putPojo(collectionPojoActuallyOnPojo, newCollectionAdapter);
+                cache.putPojo(collectionPojoActuallyOnPojo, newCollectionAdapter);
             }
         }
         
@@ -460,10 +475,10 @@ public class ObjectAdapterContext {
     private void removeFromCache(
             final RootAndCollectionAdapters rootAndCollectionAdapters, 
             final RootOid transientRootOid) {
-        LOG.debug("remapAsPersistent: {}", transientRootOid);
+        
         LOG.debug("removing root adapter from oid map");
     
-        boolean removed = oidAdapterMap.remove(transientRootOid);
+        boolean removed = oidAdapterMap().remove(transientRootOid);
         if (!removed) {
             LOG.warn("could not remove oid: {}", transientRootOid);
             // should we fail here with a more serious error?
@@ -474,7 +489,7 @@ public class ObjectAdapterContext {
         }
         for (final ObjectAdapter collectionAdapter : rootAndCollectionAdapters) {
             final Oid collectionOid = collectionAdapter.getOid();
-            removed = oidAdapterMap.remove(collectionOid);
+            removed = oidAdapterMap().remove(collectionOid);
             if (!removed) {
                 ObjectAdapterLegacy.LOG.warn("could not remove collectionOid: {}", collectionOid);
                 // should we fail here with a more serious error?
@@ -493,11 +508,8 @@ public class ObjectAdapterContext {
     @Deprecated
     public ObjectAdapter remapRecreatedPojo(ObjectAdapter adapter, final Object pojo) {
         final ObjectAdapter newAdapter = adapter.withPojo(pojo);
-        removePojo(adapter);
-        removePojo(newAdapter);
-        
-        oidAdapterMap.remove(adapter.getOid());
-        oidAdapterMap.remove(newAdapter.getOid());
+        cache.removeAdapter(adapter);
+        cache.removeAdapter(newAdapter);
 
         //FIXME[ISIS-1976] can't remove yet, does have strange side-effects 
         if(true){
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
index e60d247..7936a9d 100644
--- 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
@@ -23,7 +23,9 @@ import java.util.Objects;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.isis.commons.internal.functions._Predicates;
 import org.apache.isis.core.commons.ensure.Assert;
+import org.apache.isis.core.commons.ensure.Ensure;
 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;
@@ -149,7 +151,6 @@ class ObjectAdapterContext_AdapterManager {
         // 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));
 
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
index 77545ab..593ad6c 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
@@ -72,8 +72,9 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
         if(persistentOrValueOid != null) {
             return persistentOrValueOid;
         }
-        // Creates a new transient root for the supplied domain object
-        final RootOid rootOid = persistenceSession.createTransientOrViewModelOid(pojo);
+        final RootOid rootOid = servicesInjector.isRegisteredServiceInstance(pojo) 
+                ? persistenceSession.createPersistentOrViewModelOid(pojo) 
+                        : persistenceSession.createTransientOrViewModelOid(pojo);
         return rootOid;
     }
     
@@ -88,8 +89,11 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
             return existingOrValueAdapter;
         }
 
-        // Creates a new transient root {@link ObjectAdapter adapter} for the supplied domain
-        final RootOid rootOid = persistenceSession.createTransientOrViewModelOid(pojo);
+        final RootOid rootOid = servicesInjector.isRegisteredServiceInstance(pojo) 
+                ? persistenceSession.createPersistentOrViewModelOid(pojo) 
+                        : persistenceSession.createTransientOrViewModelOid(pojo);
+        
+//        final RootOid rootOid = persistenceSession.createTransientOrViewModelOid(pojo);
         final ObjectAdapter newAdapter = objectAdapterContext.getFactories().createRootAdapter(pojo, rootOid);
 
         return objectAdapterContext.mapAndInjectServices(newAdapter);


[isis] 13/18: ISIS-1976: remove code that seems for optimization

Posted by ah...@apache.org.
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 6bf096ebe704a7ab31b2cc583d6893ad8e15dc29
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 6 07:19:28 2018 +0200

    ISIS-1976: remove code that seems for optimization
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../persistence/adaptermanager/ObjectAdapterContext.java    | 13 +------------
 .../adaptermanager/ObjectAdapterContext_AdapterManager.java |  5 ++---
 2 files changed, 3 insertions(+), 15 deletions(-)

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 18af78f..f942f5a 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
@@ -32,6 +32,7 @@ import org.slf4j.LoggerFactory;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.commons.internal.functions._Predicates;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.ensure.Assert;
 import org.apache.isis.core.commons.ensure.Ensure;
 import org.apache.isis.core.commons.ensure.IsisAssertException;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
@@ -350,18 +351,6 @@ public class ObjectAdapterContext {
         }
     }
     
-    @Deprecated // don't expose caching
-    public void addAdapterHonoringSpecImmutability(Object pojo, ObjectAdapter adapter) {
-        // add all aggregated collections
-        final ObjectSpecification objSpec = adapter.getSpecification();
-        if (!adapter.isParentedCollection() || adapter.isParentedCollection() && !objSpec.isImmutable()) {
-            cache.putPojo(pojo, adapter);
-        }
-
-        // order is important - add to pojo map first, then identity map
-        oidAdapterMap().add(adapter.getOid(), adapter);
-    }
-    
     public ObjectAdapter disposableAdapterForViewModel(Object viewModelPojo) {
             final ObjectSpecification objectSpecification = 
                     specificationLoader.loadSpecification(viewModelPojo.getClass());
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
index 7936a9d..1af091f 100644
--- 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
@@ -23,9 +23,7 @@ import java.util.Objects;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.isis.commons.internal.functions._Predicates;
 import org.apache.isis.core.commons.ensure.Assert;
-import org.apache.isis.core.commons.ensure.Ensure;
 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;
@@ -171,7 +169,8 @@ class ObjectAdapterContext_AdapterManager {
             return adapter;
         }
 
-        objectAdapterContext.addAdapterHonoringSpecImmutability(pojo, adapter);
+        Assert.assertTrue("expected same", Objects.equals(adapter.getObject(), pojo));
+        objectAdapterContext.addAdapter(adapter);
 
         // must inject after mapping, otherwise infinite loop
         servicesInjector.injectServicesInto(pojo);


[isis] 14/18: ISIS-1976: simplify

Posted by ah...@apache.org.
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 989333f782487d2edd22e56ef236b18a55f3762c
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 6 08:06:21 2018 +0200

    ISIS-1976: simplify
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../adaptermanager/ObjectAdapterContext.java       | 69 ++++++++--------------
 .../adaptermanager/RootAndCollectionAdapters.java  |  7 +++
 2 files changed, 30 insertions(+), 46 deletions(-)

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 f942f5a..477c873 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
@@ -22,18 +22,13 @@ import java.util.List;
 import java.util.Objects;
 import java.util.UUID;
 import java.util.function.Function;
-import java.util.function.Supplier;
-
-import com.google.common.cache.Cache;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.commons.internal.functions._Predicates;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.ensure.Assert;
-import org.apache.isis.core.commons.ensure.Ensure;
 import org.apache.isis.core.commons.ensure.IsisAssertException;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
@@ -49,9 +44,7 @@ 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.persistence.adapter.PojoAdapter;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
-import org.apache.isis.core.runtime.threadpool.ThreadPoolSupport;
 
 /**
  * Encapsulate ObjectAdpater life-cycling.  
@@ -203,10 +196,6 @@ public class ObjectAdapterContext {
         return cache.lookupAdapterById(oid);
     }
     
-    private OidAdapterHashMap oidAdapterMap() {
-        return cache.oidAdapterMap;
-    }
-    
     // -- CACHING BOTH
 
     @Deprecated // don't expose caching
@@ -377,38 +366,40 @@ public class ObjectAdapterContext {
      * Note that there is no management of {@link Version}s here. That is
      * because the {@link PersistenceSession} is expected to manage this.
      *
-     * @param hintRootOid - allow a different persistent root oid to be provided.
+     * @param newRootOid - allow a different persistent root oid to be provided.
      * @param session 
      */
     @Deprecated // expected to be moved
-    public void remapAsPersistent(final ObjectAdapter adapter, RootOid hintRootOid, PersistenceSession session) {
+    public void remapAsPersistent(final ObjectAdapter adapter, RootOid newRootOid, PersistenceSession session) {
 
-        final ObjectAdapter rootAdapter = adapter.getAggregateRoot();  // TODO: REVIEW: think this is redundant; would seem this method is only ever called for roots anyway.
+        Objects.requireNonNull(newRootOid);
+        
+     // TODO: REVIEW: think this is redundant; would seem this method is only ever called for roots anyway.
+        final ObjectAdapter rootAdapter = adapter.getAggregateRoot();  
         final RootOid transientRootOid = (RootOid) rootAdapter.getOid();
+        
+        Assert.assertTrue("expected same", Objects.equals(adapter, rootAdapter));
 
         final RootAndCollectionAdapters rootAndCollectionAdapters = 
                 new RootAndCollectionAdapters(adapter, adapterManagerMixin);
 
-        removeFromCache(rootAndCollectionAdapters, transientRootOid);
+        Assert.assertTrue("expected same", Objects.equals(rootAndCollectionAdapters.getRootAdapter().getOid(), transientRootOid));
+        removeFromCache(rootAndCollectionAdapters);
         
-        // intended for testing (bit nasty)
         final RootOid persistedRootOid;
-        if(hintRootOid != null) {
-            if(hintRootOid.isTransient()) {
+        {
+            if(newRootOid.isTransient()) {
                 throw new IsisAssertException("hintRootOid must be persistent");
             }
-            final ObjectSpecId hintRootOidObjectSpecId = hintRootOid.getObjectSpecId();
+            final ObjectSpecId hintRootOidObjectSpecId = newRootOid.getObjectSpecId();
             final ObjectSpecId adapterObjectSpecId = adapter.getSpecification().getSpecId();
             if(!hintRootOidObjectSpecId.equals(adapterObjectSpecId)) {
                 throw new IsisAssertException("hintRootOid's objectType must be same as that of adapter " +
                         "(was: '" + hintRootOidObjectSpecId + "'; adapter's is " + adapterObjectSpecId + "'");
             }
             // ok
-            persistedRootOid = hintRootOid;
-        } else {
-            // normal flow - delegate to OidGenerator to obtain a persistent root oid
-            persistedRootOid = session.createPersistentOrViewModelOid(adapter.getObject());
-        }
+            persistedRootOid = newRootOid;
+        } 
 
         // associate root adapter with the new Oid, and remap
         if (LOG.isDebugEnabled()) {
@@ -438,14 +429,13 @@ public class ObjectAdapterContext {
         for (final ObjectAdapter collectionAdapter : rootAndCollectionAdapters) {
             final ParentedCollectionOid previousCollectionOid = (ParentedCollectionOid) collectionAdapter.getOid();
             final ParentedCollectionOid persistedCollectionOid = previousCollectionOid.asPersistent(persistedRootOid);
-            oidAdapterMap().add(persistedCollectionOid, collectionAdapter);
+            Assert.assertTrue("expected equal", Objects.equals(collectionAdapter.getOid(), persistedCollectionOid));
+            addAdapter(collectionAdapter);
         }
 
         // some object store implementations may replace collection instances (eg ORM may replace with a cglib-enhanced
         // proxy equivalent.  So, ensure that the collection adapters still wrap the correct pojos.
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("synchronizing collection pojos, remapping in pojo map if required");
-        }
+        LOG.debug("synchronizing collection pojos, remapping in pojo map if required");
         for (final OneToManyAssociation otma : rootAndCollectionAdapters.getCollections()) {
             final ObjectAdapter collectionAdapter = rootAndCollectionAdapters.getCollectionAdapter(otma);
 
@@ -461,28 +451,15 @@ public class ObjectAdapterContext {
         
     }
 
-    private void removeFromCache(
-            final RootAndCollectionAdapters rootAndCollectionAdapters, 
-            final RootOid transientRootOid) {
+    private void removeFromCache(final RootAndCollectionAdapters rootAndCollectionAdapters) {
+        final ObjectAdapter rootAdapter = rootAndCollectionAdapters.getRootAdapter();
         
         LOG.debug("removing root adapter from oid map");
+        cache.removeAdapter(rootAdapter);
     
-        boolean removed = oidAdapterMap().remove(transientRootOid);
-        if (!removed) {
-            LOG.warn("could not remove oid: {}", transientRootOid);
-            // should we fail here with a more serious error?
-        }
-    
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("removing collection adapter(s) from oid map");
-        }
+        LOG.debug("removing collection adapter(s) from oid map");
         for (final ObjectAdapter collectionAdapter : rootAndCollectionAdapters) {
-            final Oid collectionOid = collectionAdapter.getOid();
-            removed = oidAdapterMap().remove(collectionOid);
-            if (!removed) {
-                ObjectAdapterLegacy.LOG.warn("could not remove collectionOid: {}", collectionOid);
-                // should we fail here with a more serious error?
-            }
+            cache.removeAdapter(collectionAdapter);
         }
     }
 
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 9577ef1..19d0e0e 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
@@ -22,12 +22,17 @@ package org.apache.isis.core.runtime.system.persistence.adaptermanager;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 
 import com.google.common.collect.Maps;
 
+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.spec.feature.Contributed;
@@ -43,6 +48,8 @@ import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
  * must also be persisted.
  */
 class RootAndCollectionAdapters implements Iterable<ObjectAdapter> {
+    
+    private static final Logger LOG = LoggerFactory.getLogger(RootAndCollectionAdapters.class);
 
     private final ObjectAdapter parentAdapter;
     private final RootOid rootAdapterOid;


[isis] 12/18: ISIS-1976: restore check consistency to also check adapter's object equality

Posted by ah...@apache.org.
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 a99c1cc5b921fe872a36faba32c386d647f659cb
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 6 06:51:59 2018 +0200

    ISIS-1976: restore check consistency to also check adapter's object
    equality
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../ObjectAdapterContext_Consistency.java           | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

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
index 2d15fb0..30746a1 100644
--- 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
@@ -118,5 +118,26 @@ class ObjectAdapterContext_Consistency {
                         + mapName
                         + ": provided adapter's OID: " + adapterOid + ", \n"
                         + "but map's adapter's OID was: " + adapterAccordingToMap.getOid());
+        
+        ensureThatArg(
+                adapter.getObject(), equalTo(adapterAccordingToMap.getObject()),
+                ()->String.format("mismatch in %s (oid='%s')"
+                        + ": provided adapter's hash: %s (pojo='%s'), \n"
+                        + "but map's adapter's hash was: %s (pojo='%s')",
+                        mapName, adapterOid,
+                        Integer.toHexString(adapter.hashCode()), ""+adapter.getObject(),
+                        Integer.toHexString(adapterAccordingToMap.hashCode()), ""+adapterAccordingToMap.getObject()
+                        ));
+
+//      TODO[ISIS-1976] too strict, remove        
+//        ensureThatArg(
+//                adapter, equalTo(adapterAccordingToMap),
+//                ()->String.format("mismatch in %s (oid='%s')"
+//                        + ": provided adapter's hash: %s (pojo='%s'), \n"
+//                        + "but map's adapter's hash was: %s (pojo='%s')",
+//                        mapName, adapterOid,
+//                        Integer.toHexString(adapter.hashCode()), ""+adapter.getObject(),
+//                        Integer.toHexString(adapterAccordingToMap.hashCode()), ""+adapterAccordingToMap.getObject()
+//                        ));
     }
 }
\ No newline at end of file


[isis] 05/18: ISIS-1976: prepare removal of OA's replacePojo

Posted by ah...@apache.org.
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 543759a46cf5772bc6404079103e7eb2fb634bdb
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Sep 5 17:31:09 2018 +0200

    ISIS-1976: prepare removal of OA's replacePojo
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../system/persistence/PersistenceSession4.java    | 28 ++++++++++++++--------
 .../system/persistence/PersistenceSession5.java    | 26 +++++++++++++-------
 .../adaptermanager/ObjectAdapterContext.java       | 23 +++++++++++++-----
 3 files changed, 52 insertions(+), 25 deletions(-)

diff --git a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java
index 7c554f6..d22ef39 100644
--- a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java
+++ b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java
@@ -1140,15 +1140,17 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         final Version datastoreVersion = getVersionIfAny(pc);
 
         final RootOid originalOid;
-        ObjectAdapter adapter = objectAdapterContext.lookupAdapterFor(pojo);
-        if (adapter != null) {
-            ensureRootObject(pojo);
-            originalOid = (RootOid) adapter.getOid();
+        final ObjectAdapter originalAdapter = objectAdapterContext.lookupAdapterFor(pojo);
+        final ObjectAdapter newAdapter;
+        
+        if (originalAdapter != null) {
+            ensureRootObject(pojo); //[ahuber] while already mapped has no side-effect
+            originalOid = (RootOid) originalAdapter.getOid();
 
-            final Version originalVersion = adapter.getVersion();
+            final Version originalVersion = originalAdapter.getVersion();
 
             // sync the pojo held by the adapter with that just loaded
-            objectAdapterContext.remapRecreatedPojo(adapter, pojo);
+            newAdapter = objectAdapterContext.remapRecreatedPojo(originalAdapter, pojo);
 
             // since there was already an adapter, do concurrency check
             // (but don't set abort cause if checking is suppressed through thread-local)
@@ -1171,24 +1173,30 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
                     LOG.info("concurrency conflict detected but suppressed, on {} ({})", thisOid, otherVersion);
                 }
             }
+            
         } else {
             originalOid = createPersistentOrViewModelOid(pojo);
 
+            ObjectAdapter adapter;
+            
             // it appears to be possible that there is already an adapter for this Oid,
             // ie from ObjectStore#resolveImmediately()
             adapter = objectAdapterContext.lookupAdapterFor(originalOid);
             if (adapter != null) {
-                objectAdapterContext.remapRecreatedPojo(adapter, pojo);
+                adapter = objectAdapterContext.remapRecreatedPojo(adapter, pojo);
             } else {
                 adapter = objectAdapterContext.addRecreatedPojoToCache(originalOid, pojo);
 
                 CallbackFacet.Util.callCallback(adapter, LoadedCallbackFacet.class);
                 postLifecycleEventIfRequired(adapter, LoadedLifecycleEventFacet.class);
             }
+        
+            newAdapter = adapter;
+            
         }
-
-        adapter.setVersion(datastoreVersion);
-
+        
+        newAdapter.setVersion(datastoreVersion);
+        
         return objectAdapterContext.lookupAdapterFor(pojo);
     }
 
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 90886dc..8fdeef5 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
@@ -1132,15 +1132,17 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         final Version datastoreVersion = getVersionIfAny(pc);
 
         final RootOid originalOid;
-        ObjectAdapter adapter = objectAdapterContext.lookupAdapterFor(pojo);
-        if (adapter != null) {
+        final ObjectAdapter originalAdapter = objectAdapterContext.lookupAdapterFor(pojo);
+        final ObjectAdapter newAdapter;
+        
+        if (originalAdapter != null) {
             ensureRootObject(pojo); //[ahuber] while already mapped has no side-effect
-            originalOid = (RootOid) adapter.getOid();
+            originalOid = (RootOid) originalAdapter.getOid();
 
-            final Version originalVersion = adapter.getVersion();
+            final Version originalVersion = originalAdapter.getVersion();
 
             // sync the pojo held by the adapter with that just loaded
-            objectAdapterContext.remapRecreatedPojo(adapter, pojo);
+            newAdapter = objectAdapterContext.remapRecreatedPojo(originalAdapter, pojo);
 
             // since there was already an adapter, do concurrency check
             // (but don't set abort cause if checking is suppressed through thread-local)
@@ -1163,24 +1165,30 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
                     LOG.info("concurrency conflict detected but suppressed, on {} ({})", thisOid, otherVersion);
                 }
             }
+            
         } else {
             originalOid = createPersistentOrViewModelOid(pojo);
 
+            ObjectAdapter adapter;
+            
             // it appears to be possible that there is already an adapter for this Oid,
             // ie from ObjectStore#resolveImmediately()
             adapter = objectAdapterContext.lookupAdapterFor(originalOid);
             if (adapter != null) {
-                objectAdapterContext.remapRecreatedPojo(adapter, pojo);
+                adapter = objectAdapterContext.remapRecreatedPojo(adapter, pojo);
             } else {
                 adapter = objectAdapterContext.addRecreatedPojoToCache(originalOid, pojo);
 
                 CallbackFacet.Util.callCallback(adapter, LoadedCallbackFacet.class);
                 postLifecycleEventIfRequired(adapter, LoadedLifecycleEventFacet.class);
             }
+        
+            newAdapter = adapter;
+            
         }
-
-        adapter.setVersion(datastoreVersion);
-
+        
+        newAdapter.setVersion(datastoreVersion);
+        
         return objectAdapterContext.lookupAdapterFor(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 e7fd814..cc59c62 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
@@ -41,6 +41,7 @@ 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.persistence.adapter.PojoAdapter;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
 
 /**
@@ -468,14 +469,24 @@ public class ObjectAdapterContext {
      * @deprecated https://issues.apache.org/jira/browse/ISIS-1976
      */
     @Deprecated
-    public void remapRecreatedPojo(ObjectAdapter adapter, final Object pojo) {
-        removeAdapterFromCache(adapter);
+    public ObjectAdapter remapRecreatedPojo(ObjectAdapter adapter, final Object pojo) {
+        final ObjectAdapter newAdapter = adapter.withPojo(pojo);
+        pojoAdapterMap.remove(adapter);
+        pojoAdapterMap.remove(newAdapter);
         
-        adapter.friend().replacePojo(pojo);
-        mapAndInjectServices(adapter);
+        oidAdapterMap.remove(adapter.getOid());
+        oidAdapterMap.remove(newAdapter.getOid());
+
+        //FIXME[ISIS-1976] can't remove yet, does have strange side-effects 
+        if(true){
+            adapter.friend().replacePojo(pojo);
+            mapAndInjectServices(adapter);
+            return adapter;
+        }
+        //---
         
-        //final ObjectAdapter newAdapter = adapter.withPojo(pojo);
-        //mapAndInjectServices(newAdapter);
+        mapAndInjectServices(newAdapter);
+        return newAdapter;
     }
 
 


[isis] 01/18: ISIS-1976: make ObjectAdapter.pojo final

Posted by ah...@apache.org.
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 aa93d1eda151e0c251fe0b72ad81bcc4b7638d98
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Sep 5 15:43:52 2018 +0200

    ISIS-1976: make ObjectAdapter.pojo final
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../isis/core/metamodel/adapter/ObjectAdapter.java | 36 +++++++++++--------
 .../javautilcollection/JavaArrayFacet.java         |  2 +-
 .../BooleanPrimitiveValueSemanticsProvider.java    | 32 ++++++++---------
 .../facets/value/booleans/BooleanValueFacet.java   | 10 +++---
 .../BooleanWrapperValueSemanticsProvider.java      | 42 +++++++++++-----------
 .../runtime/persistence/adapter/PojoAdapter.java   | 34 +++++++++++++-----
 .../adaptermanager/ObjectAdapterContext.java       |  4 +--
 7 files changed, 92 insertions(+), 68 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java
index a17fac2..48b4745 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java
@@ -108,13 +108,6 @@ public interface ObjectAdapter extends Instance {
     Instance getInstance(Specification specification);
 
     /**
-     * Sometimes it is necessary to manage the replacement of the underlying
-     * domain object (by another component such as an object store). This method
-     * allows the adapter to be kept while the domain object is replaced.
-     */
-    void replacePojo(Object pojo);
-
-    /**
      * For (stand-alone) collections, returns the element type.
      *
      * <p>
@@ -169,12 +162,6 @@ public interface ObjectAdapter extends Instance {
      */
     Oid getOid();
 
-//    /**
-//     * Since {@link Oid}s are now immutable, it is the reference from the
-//     * {@link ObjectAdapter} to its {@link Oid} that must now be updated.
-//     */
-//    void replaceOid(Oid persistedOid);
-
     /**
      * Returns either itself (if this is a root) or the parented collections, the
      * adapter corresponding to their {@link ParentedCollectionOid#getRootOid() root oid}.
@@ -499,11 +486,32 @@ public interface ObjectAdapter extends Instance {
 
     /**
      * 
-     * @param persistedRootOid
+     * @param newOid
      * @return a copy of this adapter, having a new RootOid 
      * @since 2.0.0-M2
      */
     ObjectAdapter withOid(RootOid newOid);
 
+    /**
+     * 
+     * @param newPojo
+     * @return a copy of this adapter, having a new Pojo 
+     * @since 2.0.0-M2
+     */
+    ObjectAdapter withPojo(Object newPojo);
+
+    @Deprecated
+    public static interface Friend {
+      /**
+      * Sometimes it is necessary to manage the replacement of the underlying
+      * domain object (by another component such as an object store). This method
+      * allows the adapter to be kept while the domain object is replaced.
+      */
+     void replacePojo(Object pojo);
+    }
+    
+    @Deprecated
+    Friend friend();
+
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaArrayFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaArrayFacet.java
index be02897..315027c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaArrayFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaArrayFacet.java
@@ -49,7 +49,7 @@ public class JavaArrayFacet extends CollectionFacetAbstract {
         for (int i = 0; i < length; i++) {
             array[i] = initData[i].getObject();
         }
-        arrayAdapter.replacePojo(array);
+        arrayAdapter.friend().replacePojo(array);
     }
 
     /**
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/booleans/BooleanPrimitiveValueSemanticsProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/booleans/BooleanPrimitiveValueSemanticsProvider.java
index d359c94..c0bfdd3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/booleans/BooleanPrimitiveValueSemanticsProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/booleans/BooleanPrimitiveValueSemanticsProvider.java
@@ -56,21 +56,21 @@ public class BooleanPrimitiveValueSemanticsProvider extends BooleanValueSemantic
     // BooleanValueFacet impl
     // //////////////////////////////////////////////////////////////////
 
-    @Override
-    public void reset(final ObjectAdapter object) {
-        object.replacePojo(Boolean.FALSE);
-    }
-
-    @Override
-    public void set(final ObjectAdapter object) {
-        object.replacePojo(Boolean.TRUE);
-    }
-
-    @Override
-    public void toggle(final ObjectAdapter object) {
-        final boolean current = ((Boolean) object.getObject()).booleanValue();
-        final boolean toggled = !current;
-        object.replacePojo(Boolean.valueOf(toggled));
-    }
+//    @Override
+//    public void reset(final ObjectAdapter object) {
+//        object.replacePojo(Boolean.FALSE);
+//    }
+//
+//    @Override
+//    public void set(final ObjectAdapter object) {
+//        object.replacePojo(Boolean.TRUE);
+//    }
+//
+//    @Override
+//    public void toggle(final ObjectAdapter object) {
+//        final boolean current = ((Boolean) object.getObject()).booleanValue();
+//        final boolean toggled = !current;
+//        object.replacePojo(Boolean.valueOf(toggled));
+//    }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/booleans/BooleanValueFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/booleans/BooleanValueFacet.java
index 785c0e1..2e61cc2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/booleans/BooleanValueFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/booleans/BooleanValueFacet.java
@@ -26,9 +26,9 @@ public interface BooleanValueFacet extends Facet {
 
     boolean isSet(ObjectAdapter object);
 
-    void set(ObjectAdapter object);
-
-    void reset(ObjectAdapter object);
-
-    void toggle(ObjectAdapter object);
+//    void set(ObjectAdapter object);
+//
+//    void reset(ObjectAdapter object);
+//
+//    void toggle(ObjectAdapter object);
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/booleans/BooleanWrapperValueSemanticsProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/booleans/BooleanWrapperValueSemanticsProvider.java
index 234684d..69431bd 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/booleans/BooleanWrapperValueSemanticsProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/booleans/BooleanWrapperValueSemanticsProvider.java
@@ -46,26 +46,26 @@ public class BooleanWrapperValueSemanticsProvider extends BooleanValueSemanticsP
     // BooleanValueFacet impl
     // //////////////////////////////////////////////////////////////////
 
-    @Override
-    public void reset(final ObjectAdapter adapter) {
-        adapter.replacePojo(Boolean.FALSE);
-    }
-
-    @Override
-    public void set(final ObjectAdapter adapter) {
-        adapter.replacePojo(Boolean.TRUE);
-    }
-
-    @Override
-    public void toggle(final ObjectAdapter adapter) {
-        final Object currentObj = adapter.getObject();
-        if (currentObj == null) {
-            set(adapter);
-            return;
-        }
-        final boolean current = ((Boolean) currentObj).booleanValue();
-        final boolean toggled = !current;
-        adapter.replacePojo(Boolean.valueOf(toggled));
-    }
+//    @Override
+//    public void reset(final ObjectAdapter adapter) {
+//        adapter.replacePojo(Boolean.FALSE);
+//    }
+//
+//    @Override
+//    public void set(final ObjectAdapter adapter) {
+//        adapter.replacePojo(Boolean.TRUE);
+//    }
+//
+//    @Override
+//    public void toggle(final ObjectAdapter adapter) {
+//        final Object currentObj = adapter.getObject();
+//        if (currentObj == null) {
+//            set(adapter);
+//            return;
+//        }
+//        final boolean current = ((Boolean) currentObj).booleanValue();
+//        final boolean toggled = !current;
+//        adapter.replacePojo(Boolean.valueOf(toggled));
+//    }
 
 }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java
index 91a32a7..f80048c 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java
@@ -108,15 +108,15 @@ public class PojoAdapter extends InstanceAbstract implements ObjectAdapter {
         return pojo;
     }
 
-    /**
-     * Sometimes it is necessary to manage the replacement of the underlying
-     * domain object (by another component such as an object store). This method
-     * allows the adapter to be kept while the domain object is replaced.
-     */
-    @Override
-    public void replacePojo(final Object pojo) {
-        this.pojo = pojo;
-    }
+//    /**
+//     * Sometimes it is necessary to manage the replacement of the underlying
+//     * domain object (by another component such as an object store). This method
+//     * allows the adapter to be kept while the domain object is replaced.
+//     */
+//    @Override
+//    public void replacePojo(final Object pojo) {
+//        this.pojo = pojo;
+//    }
 
     // -- getOid
     @Override
@@ -401,5 +401,21 @@ public class PojoAdapter extends InstanceAbstract implements ObjectAdapter {
     public ObjectAdapter withOid(RootOid newOid) {
         return new PojoAdapter(pojo, newOid, authenticationSession, specificationLoader, persistenceSession);
     }
+    
+    @Override
+    public ObjectAdapter withPojo(Object newPojo) {
+        return new PojoAdapter(newPojo, oid, authenticationSession, specificationLoader, persistenceSession);
+    }
+
+
+    @Override
+    public Friend friend() {
+        return new Friend() {
+            @Override
+            public void replacePojo(Object pojo) {
+                PojoAdapter.this.pojo = 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 a01bb45..a13a6cc 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
@@ -427,7 +427,7 @@ public class ObjectAdapterContext {
 
             if (collectionPojoActuallyOnPojo != collectionPojoWrappedByAdapter) {
                 pojoAdapterMap.remove(collectionAdapter);
-                collectionAdapter.replacePojo(collectionPojoActuallyOnPojo);
+                collectionAdapter.friend().replacePojo(collectionPojoActuallyOnPojo);
                 pojoAdapterMap.add(collectionPojoActuallyOnPojo, collectionAdapter);
             }
         }
@@ -470,7 +470,7 @@ public class ObjectAdapterContext {
     @Deprecated
     public void remapRecreatedPojo(ObjectAdapter adapter, final Object pojo) {
         removeAdapterFromCache(adapter);
-        adapter.replacePojo(pojo);
+        adapter.friend().replacePojo(pojo);
         mapAndInjectServices(adapter);
     }
 


[isis] 18/18: ISIS-1976: further cleaning up

Posted by ah...@apache.org.
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 4b7850bff21e012e8a230919269e42e3bfeaeab9
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 6 15:11:54 2018 +0200

    ISIS-1976: further cleaning up
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../runtime/persistence/adapter/PojoAdapter.java   |  7 ++++---
 .../adaptermanager/ObjectAdapterContext.java       |  2 +-
 ...ObjectAdapterContext_ObjectAdapterProvider.java |  1 -
 .../ObjectAdapterContext_ServiceLookup.java        | 22 +++++++++++-----------
 4 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java
index c335815..2411c26 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.core.runtime.persistence.adapter;
 
+import java.util.function.Function;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,7 +57,7 @@ public class PojoAdapter extends InstanceAbstract implements ObjectAdapter {
     /**
      * can be {@link #replacePojo(Object) replace}d.
      */
-    private Object pojo;
+    private final Object pojo;
     /**
      * can be {@link #replaceOid(Oid) replace}d.
      */
@@ -83,8 +85,7 @@ public class PojoAdapter extends InstanceAbstract implements ObjectAdapter {
         this.pojo = pojo;
         this.oid = oid;
     }
-
-
+    
     // -- getSpecification
 
     /**
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 44fc112..3f43ace 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
@@ -245,7 +245,7 @@ public class ObjectAdapterContext {
     // -- SERVICE LOOKUP
     
     public ObjectAdapter lookupServiceAdapterFor(RootOid rootOid) {
-        return serviceLookupMixin.serviceAdapterFor(rootOid);
+        return serviceLookupMixin.lookupServiceAdapterFor(rootOid);
     }
     
     // -- FACTORIES
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
index b231b0c..d8f422d 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
@@ -30,7 +30,6 @@ import org.apache.isis.core.commons.ensure.Assert;
 import org.apache.isis.core.metamodel.IsisJdoMetamodelPlugin;
 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;
 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.services.ServicesInjector;
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
index ae92baa..f6ff249 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
@@ -24,6 +24,8 @@ import java.util.Objects;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.isis.commons.internal.base._Timing;
+import org.apache.isis.commons.internal.base._Timing.StopWatch;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.context._Context;
 import org.apache.isis.core.commons.ensure.Assert;
@@ -52,22 +54,16 @@ class ObjectAdapterContext_ServiceLookup {
         this.servicesInjector = servicesInjector;
     }
 
-    ObjectAdapter serviceAdapterFor(RootOid rootOid) {
+    ObjectAdapter lookupServiceAdapterFor(RootOid rootOid) {
         
         final ServicesByIdResource servicesByIdResource =
                 _Context.computeIfAbsent(ServicesByIdResource.class, cls->initLookupResource());
         
-        try {
-            final Object serviceInstance = servicesByIdResource.lookupServiceInstance(rootOid);
-            if(serviceInstance==null) {
-                return null;
-            }
-            return objectAdapterContext.getFactories().createRootAdapter(serviceInstance, rootOid);
-        } catch (Exception e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-            throw new IllegalStateException("Could not resolve service for id '" + rootOid.enStringNoVersion() + "'");
+        final Object serviceInstance = servicesByIdResource.lookupServiceInstance(rootOid);
+        if(serviceInstance==null) {
+            return null;
         }
+        return objectAdapterContext.getFactories().createRootAdapter(serviceInstance, rootOid);
         
     }
     
@@ -93,6 +89,8 @@ class ObjectAdapterContext_ServiceLookup {
         
         objectAdapterContext.printContextInfo("INIT SERVICE ID LOOKUP RESOURCE");
         
+        StopWatch watch = _Timing.now();
+        
         final ServicesByIdResource lookupResource = new ServicesByIdResource();
         
         servicesInjector.streamRegisteredServiceInstances()
@@ -102,6 +100,8 @@ class ObjectAdapterContext_ServiceLookup {
             lookupResource.servicesById.put((RootOid)serviceAdapter.getOid() , serviceAdapter.getObject());
         });
         
+        objectAdapterContext.printContextInfo("took (µs) "+watch.stop().getMicros());
+        
         return lookupResource;
     }
     


[isis] 06/18: ISIS-1976: prepare removal of OA's lookup by pojo map

Posted by ah...@apache.org.
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 b3e78b7d479aa168a89e48261ffa759a7e178e78
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Sep 5 18:21:35 2018 +0200

    ISIS-1976: prepare removal of OA's lookup by pojo map
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../metamodel/adapter/ObjectAdapterProvider.java   | 17 ++++++-
 ...ObjectAdapterContext_ObjectAdapterProvider.java | 57 ++++++++++++++++++++++
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
index ba81787..e799f5d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
@@ -22,6 +22,7 @@ import java.util.List;
 import java.util.function.Function;
 
 import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
@@ -36,6 +37,12 @@ public interface ObjectAdapterProvider {
     // -- INTERFACE
 
     /**
+     * @param pojo
+     * @return oid for the given domain object 
+     */
+    Oid oidFor(Object domainObject);
+    
+    /**
      * @return standalone (value) or root adapter
      */
     ObjectAdapter adapterFor(Object domainObject);
@@ -44,7 +51,7 @@ public interface ObjectAdapterProvider {
      * @return collection adapter.
      */
     ObjectAdapter adapterFor(
-            final Object pojo,
+            final Object domainObject,
             final ObjectAdapter parentAdapter,
             OneToManyAssociation collection);
 
@@ -72,6 +79,11 @@ public interface ObjectAdapterProvider {
         ObjectAdapterProvider getObjectAdapterProvider();
         
         @Programmatic
+        default Oid oidFor(Object domainObject) {
+            return getObjectAdapterProvider().oidFor(domainObject);
+        }
+        
+        @Programmatic
         default ObjectAdapter adapterFor(Object domainObject) {
             return getObjectAdapterProvider().adapterFor(domainObject);
         }
@@ -102,6 +114,9 @@ public interface ObjectAdapterProvider {
         }
         
     }
+
+
+    
     
 
 }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
index f54643d..ba820e3 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
@@ -28,6 +28,7 @@ import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.IsisJdoMetamodelPlugin;
 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;
 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.services.ServicesInjector;
@@ -63,6 +64,20 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
     }
 
     @Override
+    public Oid oidFor(Object pojo) {
+        if(pojo == null) {
+            return null;
+        }
+        final Oid persistentOrValueOid = persistentOrValueOid(pojo);
+        if(persistentOrValueOid != null) {
+            return persistentOrValueOid;
+        }
+        // Creates a new transient root for the supplied domain object
+        final RootOid rootOid = persistenceSession.createTransientOrViewModelOid(pojo);
+        return rootOid;
+    }
+    
+    @Override
     public ObjectAdapter adapterFor(Object pojo) {
         
         if(pojo == null) {
@@ -135,6 +150,48 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
     
     // -- HELPER
     
+    private Oid persistentOrValueOid(Object pojo) {
+        
+        Oid oid;
+
+        // equivalent to  isInstanceOfPersistable = pojo instanceof Persistable;
+        final boolean isInstanceOfPersistable = isisJdoMetamodelPlugin.isPersistenceEnhanced(pojo.getClass());
+        
+        // pojo may have been lazily loaded by object store, but we haven't yet seen it
+        if (isInstanceOfPersistable) {
+            oid = persistentOid(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 {
+            oid = null;
+        }
+
+        if(oid != null) {
+            return oid;
+        }
+        
+        // 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)) {
+            //TODO[ISIS-1976] don't need an adapter, just its oid
+            oid = objectAdapterContext.getFactories().createStandaloneAdapter(pojo).getOid(); 
+            return oid;
+        }
+
+        return null;
+    }
+    
+    protected Oid persistentOid(final Object pojo) {
+        if (persistenceSession.getPersistenceManager().getObjectId(pojo) == null) {
+            return null;
+        }
+        final RootOid oid = persistenceSession.createPersistentOrViewModelOid(pojo);
+        return oid;
+    }
+    
     private ObjectAdapter existingOrValueAdapter(Object pojo) {
 
         // attempt to locate adapter for the pojo


[isis] 16/18: ISIS-1976: lazy initialize OAs for services

Posted by ah...@apache.org.
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 9eacd3ca14c1d790940f0b61f034a603d672dab0
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 6 13:02:52 2018 +0200

    ISIS-1976: lazy initialize OAs for services
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../metamodel/adapter/ObjectAdapterProvider.java   |  18 +--
 .../core/metamodel/services/ServicesInjector.java  |   8 ++
 .../system/persistence/PersistenceSession4.java    |  65 +---------
 .../system/persistence/PersistenceSession5.java    |  65 +---------
 .../persistence/PersistenceSession5_Decouple.java  |  16 ++-
 .../system/persistence/PersistenceSession.java     |  14 ++-
 .../adaptermanager/ObjectAdapterContext.java       |  63 +++++++---
 .../ObjectAdapterContext_NewIdentifier.java        | 129 ++++++++++++++++++++
 ...ObjectAdapterContext_ObjectAdapterProvider.java | 132 +++++++++++----------
 .../ObjectAdapterContext_ServiceLookup.java        | 109 +++++++++++++++++
 10 files changed, 402 insertions(+), 217 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
index fef5bf7..3b8e0ec 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
@@ -37,11 +37,11 @@ public interface ObjectAdapterProvider {
     
     // -- INTERFACE
 
-    /**
-     * @param pojo
-     * @return oid for the given domain object 
-     */
-    Oid oidFor(Object domainObject);
+//    /**
+//     * @param pojo
+//     * @return oid for the given domain object 
+//     */
+//    Oid oidFor(Object domainObject);
     
     /**
      * @return standalone (value) or root adapter
@@ -86,10 +86,10 @@ public interface ObjectAdapterProvider {
         @Programmatic
         ObjectAdapterProvider getObjectAdapterProvider();
         
-        @Programmatic
-        default Oid oidFor(Object domainObject) {
-            return getObjectAdapterProvider().oidFor(domainObject);
-        }
+//        @Programmatic
+//        default Oid oidFor(Object domainObject) {
+//            return getObjectAdapterProvider().oidFor(domainObject);
+//        }
         
         @Programmatic
         default ObjectAdapter adapterFor(Object domainObject) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
index c345f38..444211e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
@@ -26,6 +26,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -213,6 +214,13 @@ public class ServicesInjector implements ApplicationScopedComponent {
         return Collections.unmodifiableList(services);
     }
     
+    /**
+     * @return Stream of all currently registered service instances.
+     */
+    public Stream<Object> streamRegisteredServiceInstances() {
+        return services.stream();
+    }
+    
     // -- INJECT SERVICES INTO
 
     /**
diff --git a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java
index d22ef39..e5e0b8c 100644
--- a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java
+++ b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java
@@ -1175,7 +1175,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
             }
             
         } else {
-            originalOid = createPersistentOrViewModelOid(pojo);
+            originalOid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
 
             ObjectAdapter adapter;
             
@@ -1200,70 +1200,13 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         return objectAdapterContext.lookupAdapterFor(pojo);
     }
 
-    // -- create...Oid (main API)
-    /**
-     * Create a new {@link Oid#isTransient() transient} {@link Oid} for the
-     * supplied pojo, uniquely distinguishable from any other {@link Oid}.
-     */
     @Override
-    public final RootOid createTransientOrViewModelOid(final Object pojo) {
-        return newIdentifier(pojo, Type.TRANSIENT);
-    }
-
-    /**
-     * Return an equivalent {@link RootOid}, but being persistent.
-     *
-     * <p>
-     * It is the responsibility of the implementation to determine the new unique identifier.
-     * For example, the generator may simply assign a new value from a sequence, or a GUID;
-     * or, the generator may use the oid to look up the object and inspect the object in order
-     * to obtain an application-defined value.
-     *
-     * @param pojo - being persisted
-     */
-    @Override
-    public final RootOid createPersistentOrViewModelOid(Object pojo) {
-        return newIdentifier(pojo, Type.PERSISTENT);
-    }
-
-    private RootOid newIdentifier(final Object pojo, final Type type) {
-        final ObjectSpecification spec = objectSpecFor(pojo);
-        if(spec.isService()) {
-            return newRootId(spec, SERVICE_IDENTIFIER, type);
-        }
-
-        final ViewModelFacet recreatableObjectFacet = spec.getFacet(ViewModelFacet.class);
-        final String identifier =
-                recreatableObjectFacet != null
-                ? recreatableObjectFacet.memento(pojo)
-                        : newIdentifierFor(pojo, type);
-
-                return newRootId(spec, identifier, type);
-    }
-
-    private String newIdentifierFor(final Object pojo, final Type type) {
-        return type == Type.TRANSIENT
+    public String identifierFor(final Object pojo, final Oid.State type) {
+        return type == Oid.State.TRANSIENT
                 ? UUID.randomUUID().toString()
                         : JdoObjectIdSerializer.toOidIdentifier(getPersistenceManager().getObjectId(pojo));
     }
 
-    private RootOid newRootId(final ObjectSpecification spec, final String identifier, final Type type) {
-        final Oid.State state =
-                spec.containsDoOpFacet(ViewModelFacet.class)
-                ? Oid.State.VIEWMODEL
-                        : type == Type.TRANSIENT
-                        ? Oid.State.TRANSIENT
-                                : Oid.State.PERSISTENT;
-        final ObjectSpecId objectSpecId = spec.getSpecId();
-        return new RootOid(objectSpecId, identifier, state);
-    }
-
-    private ObjectSpecification objectSpecFor(final Object pojo) {
-        final Class<?> pojoClass = pojo.getClass();
-        return getSpecificationLoader().loadSpecification(pojoClass);
-    }
-
-
 
     /**
      * Called either when an entity is initially persisted, or when an entity is updated; fires the appropriate
@@ -1313,7 +1256,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
 
         if (rootOid.isTransient()) {
             // persisting
-            final RootOid persistentOid = createPersistentOrViewModelOid(pojo);
+            final RootOid persistentOid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
 
             objectAdapterContext.remapAsPersistent(adapter, persistentOid, this);
 
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 8fdeef5..e77e5fb 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
@@ -1167,7 +1167,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
             }
             
         } else {
-            originalOid = createPersistentOrViewModelOid(pojo);
+            originalOid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
 
             ObjectAdapter adapter;
             
@@ -1192,70 +1192,13 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         return objectAdapterContext.lookupAdapterFor(pojo);
     }
 
-    // -- create...Oid (main API)
-    /**
-     * Create a new {@link Oid#isTransient() transient} {@link Oid} for the
-     * supplied pojo, uniquely distinguishable from any other {@link Oid}.
-     */
     @Override
-    public final RootOid createTransientOrViewModelOid(final Object pojo) {
-        return newIdentifier(pojo, Type.TRANSIENT);
-    }
-
-    /**
-     * Return an equivalent {@link RootOid}, but being persistent.
-     *
-     * <p>
-     * It is the responsibility of the implementation to determine the new unique identifier.
-     * For example, the generator may simply assign a new value from a sequence, or a GUID;
-     * or, the generator may use the oid to look up the object and inspect the object in order
-     * to obtain an application-defined value.
-     *
-     * @param pojo - being persisted
-     */
-    @Override
-    public final RootOid createPersistentOrViewModelOid(Object pojo) {
-        return newIdentifier(pojo, Type.PERSISTENT);
-    }
-
-    private RootOid newIdentifier(final Object pojo, final Type type) {
-        final ObjectSpecification spec = objectSpecFor(pojo);
-        if(spec.isService()) {
-            return newRootId(spec, SERVICE_IDENTIFIER, type);
-        }
-
-        final ViewModelFacet recreatableObjectFacet = spec.getFacet(ViewModelFacet.class);
-        final String identifier =
-                recreatableObjectFacet != null
-                ? recreatableObjectFacet.memento(pojo)
-                        : newIdentifierFor(pojo, type);
-
-                return newRootId(spec, identifier, type);
-    }
-
-    private String newIdentifierFor(final Object pojo, final Type type) {
-        return type == Type.TRANSIENT
+    public String identifierFor(final Object pojo, final Oid.State type) {
+        return type == Oid.State.TRANSIENT
                 ? UUID.randomUUID().toString()
                         : JdoObjectIdSerializer.toOidIdentifier(getPersistenceManager().getObjectId(pojo));
     }
 
-    private RootOid newRootId(final ObjectSpecification spec, final String identifier, final Type type) {
-        final Oid.State state =
-                spec.containsDoOpFacet(ViewModelFacet.class)
-                ? Oid.State.VIEWMODEL
-                        : type == Type.TRANSIENT
-                        ? Oid.State.TRANSIENT
-                                : Oid.State.PERSISTENT;
-        final ObjectSpecId objectSpecId = spec.getSpecId();
-        return new RootOid(objectSpecId, identifier, state);
-    }
-
-    private ObjectSpecification objectSpecFor(final Object pojo) {
-        final Class<?> pojoClass = pojo.getClass();
-        return getSpecificationLoader().loadSpecification(pojoClass);
-    }
-
-
 
     /**
      * Called either when an entity is initially persisted, or when an entity is updated; fires the appropriate
@@ -1305,7 +1248,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
 
         if (rootOid.isTransient()) {
             // persisting
-            final RootOid persistentOid = createPersistentOrViewModelOid(pojo);
+            final RootOid persistentOid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
 
             objectAdapterContext.remapAsPersistent(adapter, persistentOid, this);
 
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5_Decouple.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5_Decouple.java
index 492857b..f5054f0 100644
--- a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5_Decouple.java
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5_Decouple.java
@@ -82,7 +82,13 @@ class PersistenceSession5_Decouple  {
     public ObjectAdapter adapterFor(
             final RootOid rootOid,
             final ConcurrencyChecking concurrencyChecking) {
-
+        
+        //FIXME[ISIS-1976] guard against service lookup
+        final ObjectAdapter serviceAdapter = objectAdapterContext.lookupServiceAdapterFor(rootOid);
+        if (serviceAdapter != null) {
+            return serviceAdapter;
+        }
+        
         // attempt to locate adapter for the Oid
         ObjectAdapter adapter = objectAdapterContext.lookupAdapterFor(rootOid);
         if (adapter == null) {
@@ -98,6 +104,14 @@ class PersistenceSession5_Decouple  {
             } catch(ObjectNotFoundException ex) {
                 throw ex; // just rethrow
             } catch(RuntimeException ex) {
+                
+                System.err.println("------------------------------------------");
+                System.err.println("rootOid: "+rootOid.enString());
+                
+                ex.printStackTrace();
+                System.err.println("------------------------------------------");
+
+                
                 throw new PojoRecreationException(rootOid, ex);
             }
         }
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 1df596c..f0850e5 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
@@ -29,6 +29,7 @@ import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
 import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
+import org.apache.isis.core.metamodel.adapter.oid.Oid.State;
 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;
@@ -89,9 +90,6 @@ public interface PersistenceSession extends ObjectAdapterProvider.Delegating, Tr
 
     void close();
 
-    RootOid createTransientOrViewModelOid(Object pojo);
-    RootOid createPersistentOrViewModelOid(Object pojo);
-
     ObjectAdapter createTransientInstance(ObjectSpecification spec);
 
     ObjectAdapter createViewModelInstance(ObjectSpecification spec, String memento);
@@ -108,6 +106,14 @@ public interface PersistenceSession extends ObjectAdapterProvider.Delegating, Tr
     IsisConfiguration getConfiguration();
 
     PersistenceManager getPersistenceManager();
+    
+    /**
+     * @param pojo
+     * @param type
+     * @return String representing an object's id.
+     * @since 2.0.0-M2
+     */
+    String identifierFor(Object pojo, State type);
 
     /**
      * Convenient equivalent to {@code getPersistenceManager()}.
@@ -169,4 +175,6 @@ public interface PersistenceSession extends ObjectAdapterProvider.Delegating, Tr
     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 a665d20..b204e36 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
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.core.runtime.system.persistence.adaptermanager;
 
-import java.util.List;
 import java.util.Objects;
 import java.util.UUID;
 import java.util.function.Function;
@@ -144,6 +143,8 @@ public class ObjectAdapterContext {
     private final ObjectAdapterContext_ObjectAdapterProvider objectAdapterProviderMixin;
     private final ObjectAdapterContext_AdapterManager adapterManagerMixin;
     private final ObjectAdapterContext_MementoSupport mementoSupportMixin;
+    private final ObjectAdapterContext_ServiceLookup serviceLookupMixin;
+    private final ObjectAdapterContext_NewIdentifier newIdentifierMixin;
     
     private ObjectAdapterContext(
             ServicesInjector servicesInjector, 
@@ -155,6 +156,8 @@ public class ObjectAdapterContext {
         this.objectAdapterProviderMixin = new ObjectAdapterContext_ObjectAdapterProvider(this, persistenceSession);
         this.adapterManagerMixin = new ObjectAdapterContext_AdapterManager(this, persistenceSession);
         this.mementoSupportMixin = new ObjectAdapterContext_MementoSupport(this, persistenceSession);
+        this.serviceLookupMixin = new ObjectAdapterContext_ServiceLookup(this, servicesInjector);
+        this.newIdentifierMixin = new ObjectAdapterContext_NewIdentifier(this, persistenceSession);
         
         this.persistenceSession = persistenceSession;
         this.servicesInjector = servicesInjector;
@@ -166,15 +169,25 @@ public class ObjectAdapterContext {
                 persistenceSession);
     }
 
+    // -- DEBUG
+    
+    private void printContextInfo(String msg) {
+        String id = Integer.toHexString(this.hashCode());
+        String session = ""+persistenceSession;
+        System.out.println("!!!!!!!!!!!!!!!!!!!!!!! "+String.format("%s id=%s session='%s'", 
+                msg, id, session));
+    }
+    
     // -- LIFE-CYCLING
     
     public void open() {
+        printContextInfo("OPEN_");
         cache.open();
-        initServices();
     }
     
     public void close() {
         cache.close();
+        printContextInfo("CLOSE");
     }
     
     // -- CACHING POJO
@@ -220,6 +233,22 @@ public class ObjectAdapterContext {
         consistencyMixin.ensureMapsConsistent(oid);
     }
     
+    // -- NEW IDENTIFIER
+    
+    RootOid createTransientOrViewModelOid(final Object pojo) {
+        return newIdentifierMixin.createTransientOrViewModelOid(pojo);
+    }
+
+    public RootOid createPersistentOrViewModelOid(Object pojo) {
+        return newIdentifierMixin.createPersistentOrViewModelOid(pojo);
+    }
+    
+    // -- SERVICE LOOKUP
+    
+    public ObjectAdapter lookupServiceAdapterFor(RootOid rootOid) {
+        return serviceLookupMixin.serviceAdapterFor(rootOid);
+    }
+    
     // -- FACTORIES
     
     // package private
@@ -331,20 +360,20 @@ public class ObjectAdapterContext {
     
     // ------------------------------------------------------------------------------------------------
     
-    /**
-     * Creates {@link ObjectAdapter adapters} for the service list, ensuring that these are mapped correctly,
-     * and have the same OIDs as in any previous sessions.
-     * 
-     * @deprecated https://issues.apache.org/jira/browse/ISIS-1976
-     */
-    @Deprecated
-    private void initServices() {
-        final List<Object> registeredServices = servicesInjector.getRegisteredServices();
-        for (final Object service : registeredServices) {
-            final ObjectAdapter serviceAdapter = objectAdapterProviderMixin.adapterFor(service);
-            Assert.assertFalse("expected to not be 'transient'", serviceAdapter.getOid().isTransient());
-        }
-    }
+//    /**
+//     * Creates {@link ObjectAdapter adapters} for the service list, ensuring that these are mapped correctly,
+//     * and have the same OIDs as in any previous sessions.
+//     * 
+//     * @deprecated https://issues.apache.org/jira/browse/ISIS-1976
+//     */
+//    @Deprecated
+//    private void initServices() {
+//        final List<Object> registeredServices = servicesInjector.getRegisteredServices();
+//        for (final Object service : registeredServices) {
+//            final ObjectAdapter serviceAdapter = objectAdapterProviderMixin.adapterFor(service);
+//            Assert.assertFalse("expected to not be 'transient'", serviceAdapter.getOid().isTransient());
+//        }
+//    }
     
     public ObjectAdapter disposableAdapterForViewModel(Object viewModelPojo) {
             final ObjectSpecification objectSpecification = 
@@ -479,7 +508,7 @@ public class ObjectAdapterContext {
         return newAdapter;
     }
 
-    
+   
 
 
 }
\ No newline at end of file
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_NewIdentifier.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_NewIdentifier.java
new file mode 100644
index 0000000..31995e8
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_NewIdentifier.java
@@ -0,0 +1,129 @@
+/*
+ *  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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
+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.specloader.SpecificationLoader;
+import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+
+/**
+ * package private mixin for ObjectAdapterContext
+ * <p>
+ * Responsibility: creates RootOids 
+ * </p> 
+ * @since 2.0.0-M2
+ */
+@SuppressWarnings("unused")
+class ObjectAdapterContext_NewIdentifier {
+    
+    
+    private static final Logger LOG = LoggerFactory.getLogger(ObjectAdapterContext_NewIdentifier.class);
+    private final ObjectAdapterContext objectAdapterContext;
+    private final PersistenceSession persistenceSession;
+    private final ServicesInjector servicesInjector;
+    private final SpecificationLoader specificationLoader;
+    
+    
+    ObjectAdapterContext_NewIdentifier(ObjectAdapterContext objectAdapterContext,
+            PersistenceSession persistenceSession) {
+        this.objectAdapterContext = objectAdapterContext;
+        this.persistenceSession = persistenceSession;
+        this.servicesInjector = persistenceSession.getServicesInjector();
+        this.specificationLoader = servicesInjector.getSpecificationLoader();
+    }
+    
+//    RootOid rootOidFor(Object pojo) {
+//        final RootOid rootOid = servicesInjector.isRegisteredServiceInstance(pojo) 
+//                ? createPersistentOrViewModelOid(pojo) 
+//                        : createTransientOrViewModelOid(pojo);
+//        
+//                
+//        return rootOid;
+//    }
+    
+    
+    // -- create...Oid (main API)
+    /**
+     * Create a new {@link Oid#isTransient() transient} {@link Oid} for the
+     * supplied pojo, uniquely distinguishable from any other {@link Oid}.
+     */
+    final RootOid createTransientOrViewModelOid(final Object pojo) {
+        return newIdentifier(pojo, Oid.State.TRANSIENT);
+    }
+
+    /**
+     * Return an equivalent {@link RootOid}, but being persistent.
+     *
+     * <p>
+     * It is the responsibility of the implementation to determine the new unique identifier.
+     * For example, the generator may simply assign a new value from a sequence, or a GUID;
+     * or, the generator may use the oid to look up the object and inspect the object in order
+     * to obtain an application-defined value.
+     *
+     * @param pojo - being persisted
+     */
+    final RootOid createPersistentOrViewModelOid(Object pojo) {
+        return newIdentifier(pojo, Oid.State.PERSISTENT);
+    }
+
+    RootOid newIdentifier(final Object pojo, final Oid.State type) {
+        final ObjectSpecification spec = objectSpecFor(pojo);
+        if(spec.isService()) {
+            return newRootId(spec, PersistenceSession.SERVICE_IDENTIFIER, Oid.State.PERSISTENT); // services are always persistent
+        }
+
+        final ViewModelFacet recreatableObjectFacet = spec.getFacet(ViewModelFacet.class);
+        final String identifier =
+                recreatableObjectFacet != null
+                ? recreatableObjectFacet.memento(pojo)
+                        : persistenceSession.identifierFor(pojo, type);
+
+                return newRootId(spec, identifier, type);
+    }
+    
+    
+    private RootOid newRootId(final ObjectSpecification spec, final String identifier, final Oid.State type) {
+        final Oid.State state =
+                spec.containsDoOpFacet(ViewModelFacet.class)
+                ? Oid.State.VIEWMODEL
+                        : type == Oid.State.TRANSIENT
+                        ? Oid.State.TRANSIENT
+                                : Oid.State.PERSISTENT;
+        final ObjectSpecId objectSpecId = spec.getSpecId();
+        return new RootOid(objectSpecId, identifier, state);
+    }
+    
+    // -- HELPER
+    
+    private ObjectSpecification objectSpecFor(final Object pojo) {
+        final Class<?> pojoClass = pojo.getClass();
+        return specificationLoader.loadSpecification(pojoClass);
+    }
+
+
+    
+}
\ No newline at end of file
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
index 593ad6c..a8f33ce 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
@@ -20,11 +20,13 @@ package org.apache.isis.core.runtime.system.persistence.adaptermanager;
 
 import java.util.List;
 import java.util.function.Function;
+import java.util.stream.Collectors;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.base._Lazy;
+import org.apache.isis.core.commons.ensure.Assert;
 import org.apache.isis.core.metamodel.IsisJdoMetamodelPlugin;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
@@ -47,6 +49,7 @@ import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
  */
 class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvider {
     
+    @SuppressWarnings("unused")
     private static final Logger LOG = LoggerFactory.getLogger(ObjectAdapterContext_ObjectAdapterProvider.class);
     private final ObjectAdapterContext objectAdapterContext;
     private final PersistenceSession persistenceSession;
@@ -63,20 +66,19 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
         this.isisJdoMetamodelPlugin = IsisJdoMetamodelPlugin.get();
     }
 
-    @Override
-    public Oid oidFor(Object pojo) {
-        if(pojo == null) {
-            return null;
-        }
-        final Oid persistentOrValueOid = persistentOrValueOid(pojo);
-        if(persistentOrValueOid != null) {
-            return persistentOrValueOid;
-        }
-        final RootOid rootOid = servicesInjector.isRegisteredServiceInstance(pojo) 
-                ? persistenceSession.createPersistentOrViewModelOid(pojo) 
-                        : persistenceSession.createTransientOrViewModelOid(pojo);
-        return rootOid;
-    }
+//    @Override
+//    public Oid oidFor(Object pojo) {
+//        if(pojo == null) {
+//            return null;
+//        }
+//        final Oid persistentOrValueOid = persistentOrValueOid(pojo);
+//        if(persistentOrValueOid != null) {
+//            return persistentOrValueOid;
+//        }
+//        final RootOid rootOid = objectAdapterContext.rootOidFor(pojo);
+//        
+//        return rootOid;
+//    }
     
     @Override
     public ObjectAdapter adapterFor(Object pojo) {
@@ -89,16 +91,14 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
             return existingOrValueAdapter;
         }
 
-        final RootOid rootOid = servicesInjector.isRegisteredServiceInstance(pojo) 
-                ? persistenceSession.createPersistentOrViewModelOid(pojo) 
-                        : persistenceSession.createTransientOrViewModelOid(pojo);
+        final RootOid rootOid = objectAdapterContext.createTransientOrViewModelOid(pojo);
         
-//        final RootOid rootOid = persistenceSession.createTransientOrViewModelOid(pojo);
         final ObjectAdapter newAdapter = objectAdapterContext.getFactories().createRootAdapter(pojo, rootOid);
 
         return objectAdapterContext.mapAndInjectServices(newAdapter);
     }
-
+    
+    
     @Override
     public ObjectAdapter adapterFor(Object pojo, ObjectAdapter parentAdapter, OneToManyAssociation collection) {
 
@@ -140,66 +140,68 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
         if (persistenceSession.getPersistenceManager().getObjectId(pojo) == null) {
             return null;
         }
-        final RootOid oid = persistenceSession.createPersistentOrViewModelOid(pojo);
+        final RootOid oid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
         final ObjectAdapter adapter = objectAdapterContext.addRecreatedPojoToCache(oid, pojo);
         return adapter;
     }
     
+    private List<ObjectAdapter> initServiceAdapters() {
+        return servicesInjector.streamRegisteredServiceInstances()
+        .map(this::adapterFor)
+        .peek(serviceAdapter->{
+            Assert.assertFalse("expected to not be 'transient'", serviceAdapter.getOid().isTransient());
+        })
+        .collect(Collectors.toList());
+    }
+    
+    private _Lazy<List<ObjectAdapter>> serviceAdapters = _Lazy.of(this::initServiceAdapters);
+    
     @Override
     public List<ObjectAdapter> getServices() {
-        final List<Object> services = servicesInjector.getRegisteredServices();
-        final List<ObjectAdapter> serviceAdapters = _Lists.newArrayList();
-        for (final Object servicePojo : services) {
-            ObjectAdapter serviceAdapter = objectAdapterContext.lookupAdapterFor(servicePojo);
-            if(serviceAdapter == null) {
-                throw new IllegalStateException("ObjectAdapter for service " + servicePojo + " does not exist?!?");
-            }
-            serviceAdapters.add(serviceAdapter);
-        }
-        return serviceAdapters;
+        return serviceAdapters.get();
     }
     
     // -- HELPER
     
-    private Oid persistentOrValueOid(Object pojo) {
-        
-        Oid oid;
-
-        // equivalent to  isInstanceOfPersistable = pojo instanceof Persistable;
-        final boolean isInstanceOfPersistable = isisJdoMetamodelPlugin.isPersistenceEnhanced(pojo.getClass());
-        
-        // pojo may have been lazily loaded by object store, but we haven't yet seen it
-        if (isInstanceOfPersistable) {
-            oid = persistentOid(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 {
-            oid = null;
-        }
-
-        if(oid != null) {
-            return oid;
-        }
-        
-        // 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)) {
-            //TODO[ISIS-1976] don't need an adapter, just its oid
-            oid = objectAdapterContext.getFactories().createStandaloneAdapter(pojo).getOid(); 
-            return oid;
-        }
-
-        return null;
-    }
+//    private Oid persistentOrValueOid(Object pojo) {
+//        
+//        Oid oid;
+//
+//        // equivalent to  isInstanceOfPersistable = pojo instanceof Persistable;
+//        final boolean isInstanceOfPersistable = isisJdoMetamodelPlugin.isPersistenceEnhanced(pojo.getClass());
+//        
+//        // pojo may have been lazily loaded by object store, but we haven't yet seen it
+//        if (isInstanceOfPersistable) {
+//            oid = persistentOid(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 {
+//            oid = null;
+//        }
+//
+//        if(oid != null) {
+//            return oid;
+//        }
+//        
+//        // 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)) {
+//            //TODO[ISIS-1976] don't need an adapter, just its oid
+//            oid = objectAdapterContext.getFactories().createStandaloneAdapter(pojo).getOid(); 
+//            return oid;
+//        }
+//
+//        return null;
+//    }
     
     protected Oid persistentOid(final Object pojo) {
         if (persistenceSession.getPersistenceManager().getObjectId(pojo) == null) {
             return null;
         }
-        final RootOid oid = persistenceSession.createPersistentOrViewModelOid(pojo);
+        final RootOid oid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
         return oid;
     }
     
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
new file mode 100644
index 0000000..31d3b39
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
@@ -0,0 +1,109 @@
+/*
+ *  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.Map;
+import java.util.Objects;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.commons.internal.collections._Maps;
+import org.apache.isis.commons.internal.context._Context;
+import org.apache.isis.core.commons.ensure.Assert;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.services.ServicesInjector;
+
+/**
+ * package private mixin for ObjectAdapterContext
+ * <p>
+ * Responsibility: provides ObjectAdapters for registered services 
+ * </p> 
+ * @since 2.0.0-M2
+ */
+@SuppressWarnings("unused")
+class ObjectAdapterContext_ServiceLookup {
+    
+    
+    private static final Logger LOG = LoggerFactory.getLogger(ObjectAdapterContext_ServiceLookup.class);
+    private final ObjectAdapterContext objectAdapterContext;
+    private final ServicesInjector servicesInjector;
+    
+    ObjectAdapterContext_ServiceLookup(ObjectAdapterContext objectAdapterContext,
+            ServicesInjector servicesInjector) {
+        this.objectAdapterContext = objectAdapterContext;
+        this.servicesInjector = servicesInjector;
+    }
+
+    ObjectAdapter serviceAdapterFor(RootOid rootOid) {
+        
+        final ServicesByIdResource servicesByIdResource =
+                _Context.computeIfAbsent(ServicesByIdResource.class, cls->initLookupResource());
+        
+        try {
+            final Object serviceInstance = servicesByIdResource.lookupServiceInstance(rootOid);
+            if(serviceInstance==null) {
+                return null;
+            }
+            return objectAdapterContext.getFactories().createRootAdapter(serviceInstance, rootOid);
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            throw new IllegalStateException("Could not resolve service for id '" + rootOid.enStringNoVersion() + "'");
+        }
+        
+    }
+    
+    // -- HELPER
+    
+    /**
+     *  Application scoped resource to hold a map for looking up services by id.
+     */
+    private static class ServicesByIdResource implements AutoCloseable {
+        private final Map<RootOid, Object> servicesById = _Maps.newHashMap();
+
+        @Override
+        public void close() {
+            servicesById.clear();
+        }
+
+        public Object lookupServiceInstance(RootOid serviceRootOid) {
+            return servicesById.get(serviceRootOid);
+        }
+    }
+    
+    private ServicesByIdResource initLookupResource() {
+        
+        System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! INIT SERVICE ID LOOKUP RESOURCE");
+        
+        final ServicesByIdResource lookupResource = new ServicesByIdResource();
+        
+        servicesInjector.streamRegisteredServiceInstances()
+        .map(objectAdapterContext.getObjectAdapterProvider()::adapterFor)
+        .forEach(serviceAdapter->{
+            Assert.assertFalse("expected to not be 'transient'", serviceAdapter.getOid().isTransient());
+            lookupResource.servicesById.put((RootOid)serviceAdapter.getOid() , serviceAdapter.getObject());
+        });
+        
+        return lookupResource;
+    }
+    
+
+}
\ No newline at end of file


[isis] 10/18: ISIS-1976: make ObjectAdapter's oid immutable

Posted by ah...@apache.org.
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 b66c9edb5d01c054960ad455fd21318a061979ac
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 6 06:29:22 2018 +0200

    ISIS-1976: make ObjectAdapter's oid immutable
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../isis/core/metamodel/adapter/ObjectAdapter.java | 24 +++++++++++-----------
 .../runtime/persistence/adapter/PojoAdapter.java   | 11 ----------
 .../adaptermanager/ObjectAdapterContext.java       | 12 -----------
 .../ObjectAdapterContext_Consistency.java          |  2 +-
 4 files changed, 13 insertions(+), 36 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java
index fc67020..86dc643 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java
@@ -487,18 +487,18 @@ public interface ObjectAdapter extends Instance {
      */
     ObjectAdapter withPojo(Object newPojo);
 
-    @Deprecated
-    public static interface Friend {
-      /**
-      * Sometimes it is necessary to manage the replacement of the underlying
-      * domain object (by another component such as an object store). This method
-      * allows the adapter to be kept while the domain object is replaced.
-      */
-     void replacePojo(Object pojo);
-    }
-    
-    @Deprecated
-    Friend friend();
+//    @Deprecated
+//    public static interface Friend {
+//      /**
+//      * Sometimes it is necessary to manage the replacement of the underlying
+//      * domain object (by another component such as an object store). This method
+//      * allows the adapter to be kept while the domain object is replaced.
+//      */
+//     void replacePojo(Object pojo);
+//    }
+//    
+//    @Deprecated
+//    Friend friend();
 
 
 }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java
index f80048c..c335815 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java
@@ -407,15 +407,4 @@ public class PojoAdapter extends InstanceAbstract implements ObjectAdapter {
         return new PojoAdapter(newPojo, oid, authenticationSession, specificationLoader, persistenceSession);
     }
 
-
-    @Override
-    public Friend friend() {
-        return new Friend() {
-            @Override
-            public void replacePojo(Object pojo) {
-                PojoAdapter.this.pojo = 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 06642b2..18af78f 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
@@ -502,23 +502,11 @@ public class ObjectAdapterContext {
         return accessor.getProperty(ownerAdapter, InteractionInitiatedBy.FRAMEWORK);
     }
 
-    /**
-     * @deprecated https://issues.apache.org/jira/browse/ISIS-1976
-     */
     @Deprecated
     public ObjectAdapter remapRecreatedPojo(ObjectAdapter adapter, final Object pojo) {
         final ObjectAdapter newAdapter = adapter.withPojo(pojo);
         cache.removeAdapter(adapter);
         cache.removeAdapter(newAdapter);
-
-        //FIXME[ISIS-1976] can't remove yet, does have strange side-effects 
-        if(true){
-            adapter.friend().replacePojo(pojo);
-            mapAndInjectServices(adapter);
-            return adapter;
-        }
-        //---
-        
         mapAndInjectServices(newAdapter);
         return newAdapter;
     }
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
index d078639..2d15fb0 100644
--- 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
@@ -113,7 +113,7 @@ class ObjectAdapterContext_Consistency {
         }
 
         ensureThatArg(
-                adapter, equalTo(adapterAccordingToMap),
+                adapterOid, equalTo(adapterAccordingToMap.getOid()),
                 ()->"mismatch in "
                         + mapName
                         + ": provided adapter's OID: " + adapterOid + ", \n"


[isis] 17/18: ISIS-1976: cleaning up

Posted by ah...@apache.org.
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 f3439195726f58c5fde5c651855a220bfbe920ca
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 6 13:16:18 2018 +0200

    ISIS-1976: cleaning up
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../adaptermanager/ObjectAdapterContext.java       | 18 +-----------
 ...ObjectAdapterContext_ObjectAdapterProvider.java | 32 +++++++++++-----------
 .../ObjectAdapterContext_ServiceLookup.java        |  2 +-
 3 files changed, 18 insertions(+), 34 deletions(-)

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 b204e36..44fc112 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
@@ -135,7 +135,6 @@ public class ObjectAdapterContext {
     
     private final Cache cache = new Cache();
     
-    @SuppressWarnings("unused")
     private final PersistenceSession persistenceSession; 
     private final ServicesInjector servicesInjector;
     private final SpecificationLoader specificationLoader;
@@ -171,7 +170,7 @@ public class ObjectAdapterContext {
 
     // -- DEBUG
     
-    private void printContextInfo(String msg) {
+    void printContextInfo(String msg) {
         String id = Integer.toHexString(this.hashCode());
         String session = ""+persistenceSession;
         System.out.println("!!!!!!!!!!!!!!!!!!!!!!! "+String.format("%s id=%s session='%s'", 
@@ -360,21 +359,6 @@ public class ObjectAdapterContext {
     
     // ------------------------------------------------------------------------------------------------
     
-//    /**
-//     * Creates {@link ObjectAdapter adapters} for the service list, ensuring that these are mapped correctly,
-//     * and have the same OIDs as in any previous sessions.
-//     * 
-//     * @deprecated https://issues.apache.org/jira/browse/ISIS-1976
-//     */
-//    @Deprecated
-//    private void initServices() {
-//        final List<Object> registeredServices = servicesInjector.getRegisteredServices();
-//        for (final Object service : registeredServices) {
-//            final ObjectAdapter serviceAdapter = objectAdapterProviderMixin.adapterFor(service);
-//            Assert.assertFalse("expected to not be 'transient'", serviceAdapter.getOid().isTransient());
-//        }
-//    }
-    
     public ObjectAdapter disposableAdapterForViewModel(Object viewModelPojo) {
             final ObjectSpecification objectSpecification = 
                     specificationLoader.loadSpecification(viewModelPojo.getClass());
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
index a8f33ce..b231b0c 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
@@ -145,6 +145,15 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
         return adapter;
     }
     
+    @Override
+    public List<ObjectAdapter> getServices() {
+        return serviceAdapters.get();
+    }
+    
+    // -- HELPER
+    
+    private _Lazy<List<ObjectAdapter>> serviceAdapters = _Lazy.of(this::initServiceAdapters);
+    
     private List<ObjectAdapter> initServiceAdapters() {
         return servicesInjector.streamRegisteredServiceInstances()
         .map(this::adapterFor)
@@ -154,15 +163,6 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
         .collect(Collectors.toList());
     }
     
-    private _Lazy<List<ObjectAdapter>> serviceAdapters = _Lazy.of(this::initServiceAdapters);
-    
-    @Override
-    public List<ObjectAdapter> getServices() {
-        return serviceAdapters.get();
-    }
-    
-    // -- HELPER
-    
 //    private Oid persistentOrValueOid(Object pojo) {
 //        
 //        Oid oid;
@@ -197,13 +197,13 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
 //        return null;
 //    }
     
-    protected Oid persistentOid(final Object pojo) {
-        if (persistenceSession.getPersistenceManager().getObjectId(pojo) == null) {
-            return null;
-        }
-        final RootOid oid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
-        return oid;
-    }
+//    private Oid persistentOid(final Object pojo) {
+//        if (persistenceSession.getPersistenceManager().getObjectId(pojo) == null) {
+//            return null;
+//        }
+//        final RootOid oid = objectAdapterContext.createPersistentOrViewModelOid(pojo);
+//        return oid;
+//    }
     
     private ObjectAdapter existingOrValueAdapter(Object pojo) {
 
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
index 31d3b39..ae92baa 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
@@ -91,7 +91,7 @@ class ObjectAdapterContext_ServiceLookup {
     
     private ServicesByIdResource initLookupResource() {
         
-        System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! INIT SERVICE ID LOOKUP RESOURCE");
+        objectAdapterContext.printContextInfo("INIT SERVICE ID LOOKUP RESOURCE");
         
         final ServicesByIdResource lookupResource = new ServicesByIdResource();
         


[isis] 02/18: ISIS-1976: removing ObjectAdapter.replacePojo(Object pojo)

Posted by ah...@apache.org.
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 1f5520f43c39be8f55d43f6ea22b7020765e374b
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Sep 5 15:56:32 2018 +0200

    ISIS-1976: removing ObjectAdapter.replacePojo(Object pojo)
    
    also cleaning up
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../apache/isis/core/metamodel/adapter/ObjectAdapter.java   | 13 -------------
 .../facets/actions/action/invocation/CommandUtil.java       |  2 +-
 .../collections/javautilcollection/JavaArrayFacet.java      |  3 ++-
 .../collections/javautilcollection/JavaCollectionFacet.java |  9 +++++----
 .../facets/collections/modify/CollectionFacet.java          |  3 ++-
 .../specloader/specimpl/OneToOneAssociationDefault.java     |  2 +-
 .../standalonelist/CollectionFacetOnStandaloneList.java     |  3 ++-
 .../viewer/wicket/model/mementos/ObjectAdapterMemento.java  |  2 +-
 .../viewer/wicket/model/models/EntityCollectionModel.java   |  2 +-
 9 files changed, 15 insertions(+), 24 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java
index 48b4745..fc67020 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java
@@ -469,19 +469,6 @@ public interface ObjectAdapter extends Instance {
             return Util::unwrap;
         }
 
-        public static Function<Object, ObjectAdapter> adapterForUsing(final ObjectAdapterProvider adapterProvider) {
-            return adapterProvider::adapterFor;
-        }
-
-        @Deprecated
-        public static com.google.common.base.Function<Object, ObjectAdapter> adapter_ForUsing(final ObjectAdapterProvider adapterProvider) {
-            return new com.google.common.base.Function<Object, ObjectAdapter>() {
-                @Override
-                public ObjectAdapter apply(final Object pojo) {
-                    return adapterProvider.adapterFor(pojo);
-                }
-            };
-        }
     }
 
     /**
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/CommandUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/CommandUtil.java
index aea2939..f0f9112 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/CommandUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/CommandUtil.java
@@ -103,7 +103,7 @@ public class CommandUtil {
 
     public static ObjectAdapter[] adaptersFor(final Object[] args, final ObjectAdapterProvider adapterProvider) {
         return _NullSafe.stream(args)
-                .map(ObjectAdapter.Functions.adapterForUsing(adapterProvider))
+                .map(adapterProvider::adapterFor)
                 .collect(_Arrays.toArray(ObjectAdapter.class, _NullSafe.size(args)));
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaArrayFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaArrayFacet.java
index 315027c..94ffea2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaArrayFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaArrayFacet.java
@@ -43,13 +43,14 @@ public class JavaArrayFacet extends CollectionFacetAbstract {
      * Expected to be called with a {@link ObjectAdapter} wrapping an array.
      */
     @Override
-    public void init(final ObjectAdapter arrayAdapter, final ObjectAdapter[] initData) {
+    public ObjectAdapter init(final ObjectAdapter arrayAdapter, final ObjectAdapter[] initData) {
         final int length = initData.length;
         final Object[] array = new Object[length];
         for (int i = 0; i < length; i++) {
             array[i] = initData[i].getObject();
         }
         arrayAdapter.friend().replacePojo(array);
+        return arrayAdapter;
     }
 
     /**
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaCollectionFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaCollectionFacet.java
index 84360f9..a1fe10d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaCollectionFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaCollectionFacet.java
@@ -21,10 +21,10 @@ package org.apache.isis.core.metamodel.facets.collections.javautilcollection;
 
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.function.Function;
 
 import com.google.common.collect.Collections2;
 
-import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -40,13 +40,14 @@ public class JavaCollectionFacet extends CollectionFacetAbstract {
     }
     
     @Override
-    public void init(final ObjectAdapter collection, final ObjectAdapter[] initData) {
+    public ObjectAdapter init(final ObjectAdapter collection, final ObjectAdapter[] initData) {
         final Collection<? super Object> pojoCollection = pojoCollection(collection);
         pojoCollection.clear();
         for (final ObjectAdapter element : initData) {
             final Object pojo = element.getObject();
             pojoCollection.add(pojo);
         }
+        return collection;
     }
     
     @Override
@@ -55,8 +56,8 @@ public class JavaCollectionFacet extends CollectionFacetAbstract {
         
         //TODO [ahuber] java doc states, this is a live view, don't know if this is needed, 
         // or if a copy is sufficient
-        return Collections2.transform(pojoCollection,
-                ObjectAdapter.Functions.adapter_ForUsing(getObjectAdapterProvider()));
+        return Collections2.transform(pojoCollection, adapterProvider::adapterFor);
+                
     }
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionFacet.java
index 97d3798..fb6019f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionFacet.java
@@ -56,8 +56,9 @@ public interface CollectionFacet extends Facet {
 
     /**
      * Set the contents of this collection.
+     * @return a possibly new instance
      */
-    void init(ObjectAdapter collectionAdapter, ObjectAdapter[] elements);
+    ObjectAdapter init(ObjectAdapter collectionAdapter, ObjectAdapter[] elements);
 
     /**
      * Convenience method that returns the {@link TypeOfFacet} on this facet's
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
index bd313fa..7418bda 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
@@ -272,7 +272,7 @@ public class OneToOneAssociationDefault extends ObjectAssociationAbstract implem
                 getSpecificationLoader(),
                 interactionInitiatedBy);
         List<ObjectAdapter> adapters = _NullSafe.stream(pojoOptions)
-                .map( ObjectAdapter.Functions.adapterForUsing( getObjectAdapterProvider() ) )
+                .map(  getObjectAdapterProvider()::adapterFor )
                 .collect(Collectors.toList());
         return adapters.toArray(new ObjectAdapter[]{});
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/standalonelist/CollectionFacetOnStandaloneList.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/standalonelist/CollectionFacetOnStandaloneList.java
index cca3801..e03fda9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/standalonelist/CollectionFacetOnStandaloneList.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/standalonelist/CollectionFacetOnStandaloneList.java
@@ -64,7 +64,8 @@ public class CollectionFacetOnStandaloneList extends CollectionFacetAbstract {
      * Does nothing.
      */
     @Override
-    public void init(final ObjectAdapter collection, final ObjectAdapter[] initData) {
+    public ObjectAdapter init(final ObjectAdapter collection, final ObjectAdapter[] initData) {
+        return collection;
     }
 
 }
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java
index f4079cb..243cbac 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java
@@ -134,7 +134,7 @@ public class ObjectAdapterMemento implements Serializable {
                 final List<Object> listOfPojos =
                         _Lists.transform(oam.list, Functions.toPojo(persistenceSession, specificationLoader));
 
-                return ObjectAdapter.Functions.adapterForUsing(persistenceSession).apply(listOfPojos);
+                return persistenceSession.adapterFor(listOfPojos);
             }
 
             @Override
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
index fafc912..5970611 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
@@ -176,7 +176,7 @@ UiHintContainer {
 
                 final List<ObjectAdapter> adapterList =
                         _Lists.transform(objectList,
-                                ObjectAdapter.Functions.adapterForUsing( entityCollectionModel.getPersistenceSession() ));
+                                entityCollectionModel.getPersistenceSession()::adapterFor);
 
                 return adapterList;
             }


[isis] 04/18: ISIS-1976: let ObjectAdapterContext.replaceRootAdapter(ObjectAdapter, RootAndCollectionAdapters) no longer use OA's replacePojo

Posted by ah...@apache.org.
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 63a89c8af0463c6bc8a724465ab1f014631390f5
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Sep 5 16:16:10 2018 +0200

    ISIS-1976: let ObjectAdapterContext.replaceRootAdapter(ObjectAdapter,
    RootAndCollectionAdapters) no longer use OA's replacePojo
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../system/persistence/adaptermanager/ObjectAdapterContext.java   | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

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 a13a6cc..e7fd814 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
@@ -427,8 +427,8 @@ public class ObjectAdapterContext {
 
             if (collectionPojoActuallyOnPojo != collectionPojoWrappedByAdapter) {
                 pojoAdapterMap.remove(collectionAdapter);
-                collectionAdapter.friend().replacePojo(collectionPojoActuallyOnPojo);
-                pojoAdapterMap.add(collectionPojoActuallyOnPojo, collectionAdapter);
+                final ObjectAdapter newCollectionAdapter = collectionAdapter.withPojo(collectionPojoActuallyOnPojo);
+                pojoAdapterMap.add(collectionPojoActuallyOnPojo, newCollectionAdapter);
             }
         }
         
@@ -470,8 +470,12 @@ public class ObjectAdapterContext {
     @Deprecated
     public void remapRecreatedPojo(ObjectAdapter adapter, final Object pojo) {
         removeAdapterFromCache(adapter);
+        
         adapter.friend().replacePojo(pojo);
         mapAndInjectServices(adapter);
+        
+        //final ObjectAdapter newAdapter = adapter.withPojo(pojo);
+        //mapAndInjectServices(newAdapter);
     }
 
 


[isis] 15/18: ISIS-1976: further simplify

Posted by ah...@apache.org.
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 9e286dcfc3555f66d4f3283fc891dc17307f9bff
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 6 09:13:00 2018 +0200

    ISIS-1976: further simplify
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../commons/internal/exceptions/_Exceptions.java   | 20 ++++++
 .../adaptermanager/ObjectAdapterContext.java       | 78 ++++++++++++----------
 .../ObjectAdapterContext_AdapterManager.java       | 24 ++-----
 .../ObjectAdapterContext_Consistency.java          |  8 +--
 .../adaptermanager/RootAndCollectionAdapters.java  | 13 ++--
 5 files changed, 76 insertions(+), 67 deletions(-)

diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/exceptions/_Exceptions.java b/core/commons/src/main/java/org/apache/isis/commons/internal/exceptions/_Exceptions.java
index 968f0f9..214936a 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/exceptions/_Exceptions.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/exceptions/_Exceptions.java
@@ -81,6 +81,26 @@ public final class _Exceptions {
     public static IllegalStateException notImplemented() {
         return new IllegalStateException("internal error: code was reached, that is not implemented yet");
     }
+    
+    /**
+    * Used to hide from the compiler the fact, that this call always throws.
+    *
+    * <pre>{
+    *    throw unexpectedCodeReach();
+    *    return 0; // won't compile: unreachable code
+    *}</pre>
+    *
+    * hence ...
+    *
+    * <pre>{
+    *    throwUnexpectedCodeReach();
+    *    return 0;
+    *}</pre>
+    *
+    */
+    public static void throwUnexpectedCodeReach() {
+        throw unexpectedCodeReach();
+    }
 
     /**
      * Used to hide from the compiler the fact, that this call always throws.
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 477c873..a665d20 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
@@ -26,7 +26,6 @@ import java.util.function.Function;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-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.ensure.IsisAssertException;
@@ -137,6 +136,7 @@ public class ObjectAdapterContext {
     
     private final Cache cache = new Cache();
     
+    @SuppressWarnings("unused")
     private final PersistenceSession persistenceSession; 
     private final ServicesInjector servicesInjector;
     private final SpecificationLoader specificationLoader;
@@ -179,50 +179,51 @@ public class ObjectAdapterContext {
     
     // -- CACHING POJO
 
-    @Deprecated // don't expose caching
-    protected ObjectAdapter lookupAdapterByPojo(Object pojo) {
+    // package private // don't expose caching
+    ObjectAdapter lookupAdapterByPojo(Object pojo) {
         return cache.lookupAdapterByPojo(pojo);
     }
     
-    @Deprecated // don't expose caching
-    public boolean containsAdapterForPojo(Object pojo) {
+    // package private // don't expose caching
+    boolean containsAdapterForPojo(Object pojo) {
         return lookupAdapterByPojo(pojo)!=null;
     }
     
     // -- CACHING OID
     
-    @Deprecated // don't expose caching
-    protected ObjectAdapter lookupAdapterById(Oid oid) {
+    // package private // don't expose caching
+    ObjectAdapter lookupAdapterById(Oid oid) {
         return cache.lookupAdapterById(oid);
     }
     
     // -- CACHING BOTH
 
-    @Deprecated // don't expose caching
-    public void addAdapter(ObjectAdapter adapter) {
+    // package private // don't expose caching
+    void addAdapter(ObjectAdapter adapter) {
         cache.addAdapter(adapter);
     }
     
-    @Deprecated // don't expose caching
-    public void removeAdapter(ObjectAdapter adapter) {
+    // package private // don't expose caching
+    void removeAdapter(ObjectAdapter adapter) {
         cache.removeAdapter(adapter);
     }
     
     // -- CACHE CONSISTENCY
     
-    @Deprecated // don't expose caching
-    public void ensureMapsConsistent(final ObjectAdapter adapter) {
+    // package private // don't expose caching
+    void ensureMapsConsistent(final ObjectAdapter adapter) {
         consistencyMixin.ensureMapsConsistent(adapter);
     }
 
-    @Deprecated // don't expose caching
-    public void ensureMapsConsistent(final Oid oid) {
+    // package private // don't expose caching
+    void ensureMapsConsistent(final Oid oid) {
         consistencyMixin.ensureMapsConsistent(oid);
     }
     
     // -- FACTORIES
     
-    public static interface ObjectAdapterFactories {
+    // package private
+    static interface ObjectAdapterFactories {
         
         /**
          * Creates (but does not {@link #mapAndInjectServices(ObjectAdapter) map}) a new
@@ -266,7 +267,8 @@ public class ObjectAdapterContext {
     
     private final ObjectAdapterFactories objectAdapterFactories;
     
-    public ObjectAdapterFactories getFactories() {
+    // package private
+    ObjectAdapterFactories getFactories() {
         return objectAdapterFactories;
     }
     
@@ -289,11 +291,20 @@ public class ObjectAdapterContext {
     
     @Deprecated // don't expose caching
     public ObjectAdapter lookupAdapterFor(final Oid oid) {
-        return adapterManagerMixin.lookupAdapterFor(oid);
+        Objects.requireNonNull(oid);
+        consistencyMixin.ensureMapsConsistent(oid);
+        return cache.lookupAdapterById(oid);
     }
     
-    @Deprecated // don't expose caching
-    public void removeAdapterFromCache(final ObjectAdapter adapter) {
+    // package private
+    ObjectAdapter lookupParentedCollectionAdapter(ParentedCollectionOid collectionOid) {
+        Objects.requireNonNull(collectionOid);
+        consistencyMixin.ensureMapsConsistent(collectionOid);
+        return cache.lookupAdapterById(collectionOid);
+    }
+    
+    // package private // don't expose caching
+    void removeAdapterFromCache(final ObjectAdapter adapter) {
         adapterManagerMixin.removeAdapterFromCache(adapter);
     }
     
@@ -331,12 +342,7 @@ public class ObjectAdapterContext {
         final List<Object> registeredServices = servicesInjector.getRegisteredServices();
         for (final Object service : registeredServices) {
             final ObjectAdapter serviceAdapter = objectAdapterProviderMixin.adapterFor(service);
-            
-            // remap as Persistent if required
-            if (serviceAdapter.getOid().isTransient()) {
-                _Exceptions.unexpectedCodeReach();
-                //remapAsPersistent(serviceAdapter, null, persistenceSession);
-            }
+            Assert.assertFalse("expected to not be 'transient'", serviceAdapter.getOid().isTransient());
         }
     }
     
@@ -349,7 +355,8 @@ public class ObjectAdapterContext {
             return createdAdapter;
     }
     
-    public ObjectAdapter adapterForViewModel(Object viewModelPojo, Function<ObjectSpecId, RootOid> rootOidFactory) {
+    // package private
+    ObjectAdapter adapterForViewModel(Object viewModelPojo, Function<ObjectSpecId, RootOid> rootOidFactory) {
         ObjectAdapter viewModelAdapter = adapterManagerMixin.lookupAdapterFor(viewModelPojo);
         if(viewModelAdapter == null) {
             final ObjectSpecification objectSpecification = 
@@ -370,20 +377,16 @@ public class ObjectAdapterContext {
      * @param session 
      */
     @Deprecated // expected to be moved
-    public void remapAsPersistent(final ObjectAdapter adapter, RootOid newRootOid, PersistenceSession session) {
+    public void remapAsPersistent(final ObjectAdapter rootAdapter, RootOid newRootOid, PersistenceSession session) {
 
         Objects.requireNonNull(newRootOid);
+        Assert.assertFalse("expected to not be a parented collection", rootAdapter.isParentedCollection());
         
-     // TODO: REVIEW: think this is redundant; would seem this method is only ever called for roots anyway.
-        final ObjectAdapter rootAdapter = adapter.getAggregateRoot();  
         final RootOid transientRootOid = (RootOid) rootAdapter.getOid();
         
-        Assert.assertTrue("expected same", Objects.equals(adapter, rootAdapter));
-
         final RootAndCollectionAdapters rootAndCollectionAdapters = 
-                new RootAndCollectionAdapters(adapter, adapterManagerMixin);
+                new RootAndCollectionAdapters(rootAdapter, this);
 
-        Assert.assertTrue("expected same", Objects.equals(rootAndCollectionAdapters.getRootAdapter().getOid(), transientRootOid));
         removeFromCache(rootAndCollectionAdapters);
         
         final RootOid persistedRootOid;
@@ -392,7 +395,7 @@ public class ObjectAdapterContext {
                 throw new IsisAssertException("hintRootOid must be persistent");
             }
             final ObjectSpecId hintRootOidObjectSpecId = newRootOid.getObjectSpecId();
-            final ObjectSpecId adapterObjectSpecId = adapter.getSpecification().getSpecId();
+            final ObjectSpecId adapterObjectSpecId = rootAdapter.getSpecification().getSpecId();
             if(!hintRootOidObjectSpecId.equals(adapterObjectSpecId)) {
                 throw new IsisAssertException("hintRootOid's objectType must be same as that of adapter " +
                         "(was: '" + hintRootOidObjectSpecId + "'; adapter's is " + adapterObjectSpecId + "'");
@@ -406,8 +409,7 @@ public class ObjectAdapterContext {
             LOG.debug("replacing root adapter and re-adding into maps; oid is now: {} (was: {})", persistedRootOid.enString(), transientRootOid.enString());
         }
         
-        final ObjectAdapter adapterReplacement = adapter.withOid(persistedRootOid); 
-        
+        final ObjectAdapter adapterReplacement = rootAdapter.withOid(persistedRootOid); 
         replaceRootAdapter(adapterReplacement, rootAndCollectionAdapters);
         
         if (LOG.isDebugEnabled()) {
@@ -477,5 +479,7 @@ public class ObjectAdapterContext {
         return newAdapter;
     }
 
+    
+
 
 }
\ No newline at end of file
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
index 1af091f..fc50a81 100644
--- 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
@@ -23,6 +23,7 @@ import java.util.Objects;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 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;
@@ -43,6 +44,7 @@ class ObjectAdapterContext_AdapterManager {
     
     private static final Logger LOG = LoggerFactory.getLogger(ObjectAdapterContext_AdapterManager.class);
     private final ObjectAdapterContext objectAdapterContext;
+    @SuppressWarnings("unused")
     private final PersistenceSession persistenceSession;
     private final ServicesInjector servicesInjector; 
     
@@ -68,10 +70,8 @@ class ObjectAdapterContext_AdapterManager {
      * @param recreatedPojo - already known to the object store impl, or a service
      */
     //@Override
-    public ObjectAdapter addRecreatedPojoToCache(Oid oid, Object recreatedPojo) {
+    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;
@@ -80,6 +80,7 @@ class ObjectAdapterContext_AdapterManager {
         // attempt to locate adapter for the Oid
         final ObjectAdapter adapterLookedUpByOid = lookupAdapterFor(oid);
         if (adapterLookedUpByOid != null) {
+            _Exceptions.throwUnexpectedCodeReach();
             return adapterLookedUpByOid;
         }
 
@@ -128,23 +129,6 @@ class ObjectAdapterContext_AdapterManager {
         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);
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
index 30746a1..2f26bff 100644
--- 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
@@ -35,9 +35,11 @@ import org.apache.isis.core.metamodel.adapter.oid.Oid;
  * Responsibility: ObjectAdapter Cache/Map consistency
  * </p> 
  * @since 2.0.0-M2
+ * @deprecated expected to be made obsolete
  */
 class ObjectAdapterContext_Consistency {
     
+    @SuppressWarnings("unused")
     private static final Logger LOG = LoggerFactory.getLogger(ObjectAdapterContext_Consistency.class);
     private final ObjectAdapterContext objectAdapterContext;
     
@@ -47,9 +49,8 @@ class ObjectAdapterContext_Consistency {
 
     /**
      * Fail early if any problems.
-     * @deprecated https://issues.apache.org/jira/browse/ISIS-1976
      */
-    protected void ensureMapsConsistent(final ObjectAdapter adapter) {
+    void ensureMapsConsistent(final ObjectAdapter adapter) {
         if (adapter.isValue()) {
             return;
         }
@@ -62,9 +63,8 @@ class ObjectAdapterContext_Consistency {
 
     /**
      * Fail early if any problems.
-     * @deprecated https://issues.apache.org/jira/browse/ISIS-1976
      */
-    protected void ensureMapsConsistent(final Oid oid) {
+    void ensureMapsConsistent(final Oid oid) {
         Objects.requireNonNull(oid);
 
         final ObjectAdapter adapter = objectAdapterContext.lookupAdapterById(oid);
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 19d0e0e..fed267d 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
@@ -22,7 +22,6 @@ package org.apache.isis.core.runtime.system.persistence.adaptermanager;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
 
 import com.google.common.collect.Maps;
@@ -32,7 +31,6 @@ 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.spec.feature.Contributed;
@@ -49,8 +47,10 @@ import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
  */
 class RootAndCollectionAdapters implements Iterable<ObjectAdapter> {
     
+    @SuppressWarnings("unused")
     private static final Logger LOG = LoggerFactory.getLogger(RootAndCollectionAdapters.class);
 
+    private final ObjectAdapterContext context;
     private final ObjectAdapter parentAdapter;
     private final RootOid rootAdapterOid;
 
@@ -58,11 +58,12 @@ class RootAndCollectionAdapters implements Iterable<ObjectAdapter> {
 
     public RootAndCollectionAdapters(
             final ObjectAdapter parentAdapter,
-            final ObjectAdapterContext_AdapterManager adapterManagerMixin) {
+            final ObjectAdapterContext context) {
         Assert.assertNotNull(parentAdapter);
         this.rootAdapterOid = (RootOid) parentAdapter.getOid();
         this.parentAdapter = parentAdapter;
-        addCollectionAdapters(adapterManagerMixin);
+        this.context = context;
+        addCollectionAdapters();
     }
 
     public ObjectAdapter getRootAdapter() {
@@ -102,10 +103,10 @@ class RootAndCollectionAdapters implements Iterable<ObjectAdapter> {
     // Helpers
     ////////////////////////////////////////////////////////////////////////
 
-    private void addCollectionAdapters(ObjectAdapterContext_AdapterManager adapterManagerMixin) {
+    private void addCollectionAdapters() {
         for (final OneToManyAssociation otma : parentAdapter.getSpecification().getCollections(Contributed.EXCLUDED)) {
             final ParentedCollectionOid collectionOid = new ParentedCollectionOid((RootOid) rootAdapterOid, otma);
-            final ObjectAdapter collectionAdapter = adapterManagerMixin.lookupAdapterFor(collectionOid);
+            final ObjectAdapter collectionAdapter = context.lookupParentedCollectionAdapter(collectionOid);
             if (collectionAdapter != null) {
                 // collection adapters are lazily created and so there may not be one.
                 addCollectionAdapter(otma, collectionAdapter);


[isis] 03/18: ISIS-1976: let JavaCollectionFacet no longer change OA's pojo

Posted by ah...@apache.org.
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 afd1fb976912dff321ee1dd105cbcc5e6df33be9
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Sep 5 16:06:51 2018 +0200

    ISIS-1976: let JavaCollectionFacet no longer change OA's pojo
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../facets/collections/javautilcollection/JavaArrayFacet.java    | 3 +--
 .../collections/javautilcollection/JavaCollectionFacet.java      | 9 ---------
 .../adaptermanager/ObjectAdapterContext_MementoSupport.java      | 6 +++---
 3 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaArrayFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaArrayFacet.java
index 94ffea2..5a86a12 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaArrayFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaArrayFacet.java
@@ -49,8 +49,7 @@ public class JavaArrayFacet extends CollectionFacetAbstract {
         for (int i = 0; i < length; i++) {
             array[i] = initData[i].getObject();
         }
-        arrayAdapter.friend().replacePojo(array);
-        return arrayAdapter;
+        return arrayAdapter.withPojo(array);  
     }
 
     /**
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaCollectionFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaCollectionFacet.java
index a1fe10d..63a5f55 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaCollectionFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/javautilcollection/JavaCollectionFacet.java
@@ -21,7 +21,6 @@ package org.apache.isis.core.metamodel.facets.collections.javautilcollection;
 
 import java.util.Collection;
 import java.util.Iterator;
-import java.util.function.Function;
 
 import com.google.common.collect.Collections2;
 
@@ -79,12 +78,4 @@ public class JavaCollectionFacet extends CollectionFacetAbstract {
         return (Collection<? super Object>) collectionAdapter.getObject();
     }
 
-    // //////////////////////////////////////////////////////////////////////
-    // Dependencies (from constructor)
-    // //////////////////////////////////////////////////////////////////////
-
-    private ObjectAdapterProvider getObjectAdapterProvider() {
-        return adapterProvider;
-    }
-
 }
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
index acb2e11..beaadae 100644
--- 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
@@ -74,7 +74,7 @@ class ObjectAdapterContext_MementoSupport implements MementoRecreateObjectSuppor
 
             final Object recreatedPojo = persistenceSession.instantiateAndInjectServices(spec);
             adapter = objectAdapterContext.addRecreatedPojoToCache(oid, recreatedPojo);
-            populateCollection(adapter, (CollectionData) data);
+            adapter = 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);
@@ -138,14 +138,14 @@ class ObjectAdapterContext_MementoSupport implements MementoRecreateObjectSuppor
         }
     }
     
-    private void populateCollection(final ObjectAdapter collectionAdapter, final CollectionData state) {
+    private ObjectAdapter 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);
+        return facet.init(collectionAdapter, initData);
     }
     
     private void updateFieldsAndResolveState(final ObjectAdapter objectAdapter, final Data data) {


[isis] 11/18: ISIS-1976: improve code readability

Posted by ah...@apache.org.
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 30d9e29e779c730c6b6bfe1ae84c1d7524554cca
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 6 06:36:00 2018 +0200

    ISIS-1976: improve code readability
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../core/metamodel/services/ServicesInjector.java    | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
index d293abc..c345f38 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
@@ -146,15 +146,6 @@ public class ServicesInjector implements ApplicationScopedComponent {
         serviceByConcreteType.clear();
         autowire();
     }
-    
-    private Map<Class<?>, Object> initServiceByConcreteType(){
-        final Map<Class<?>, Object> map = _Maps.newHashMap();
-        for (Object service : services) {
-            final Class<?> concreteType = service.getClass();
-            map.put(concreteType, service);
-        }
-        return map;
-    }
 
     public boolean isRegisteredService(final Class<?> cls) {
         return serviceByConcreteType.get().containsKey(cls);
@@ -457,6 +448,17 @@ public class ServicesInjector implements ApplicationScopedComponent {
         .forEach(filteredServicesAndContainer::add);
     }
 
+    // -- LAZY INIT
+    
+    private Map<Class<?>, Object> initServiceByConcreteType(){
+        final Map<Class<?>, Object> map = _Maps.newHashMap();
+        for (Object service : services) {
+            final Class<?> concreteType = service.getClass();
+            map.put(concreteType, service);
+        }
+        return map;
+    }
+    
     // -- REFLECTIVE PREDICATES
 
     private static final Predicate<Object> isOfType(final Class<?> cls) {


[isis] 08/18: ISIS-1976: improve the ObjectAdapterProvider interface (API)

Posted by ah...@apache.org.
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 11aa13574b4109eaae9530f95b3d3399b3a508b1
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Sep 5 20:41:07 2018 +0200

    ISIS-1976: improve the ObjectAdapterProvider interface (API)
    
    also prepare for removal of the OA by pojo lookup map
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../metamodel/adapter/ObjectAdapterProvider.java   | 28 ++++++++--
 ...ObjectFacetDeclarativeInitializingAbstract.java |  3 +-
 .../adaptermanager/ObjectAdapterContext.java       | 64 ++++++++++++++--------
 .../ObjectAdapterContext_AdapterManager.java       | 30 ++++++++++
 ...ObjectAdapterContext_ObjectAdapterProvider.java | 11 +++-
 5 files changed, 103 insertions(+), 33 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
index e799f5d..fef5bf7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
@@ -25,6 +25,7 @@ import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.core.metamodel.adapter.oid.Oid;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 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;
 
 /**
@@ -56,12 +57,19 @@ public interface ObjectAdapterProvider {
             OneToManyAssociation collection);
 
     /**
-     * @param viewModelPojo
-     * @return an ObjectAdapter 'bypassing mapping', that holds the ObjectSpecification
-     * FIXME[ISIS-1976] Note: whether or not 'bypassing mapping' should not be exposed by the API.
-     * So this further needs refactoring. 
+     * Returns an ObjectAdapter that holds the ObjectSpecification used for 
+     * interrogating the domain object's metadata. 
+     * <p>
+     * Does _not_ perform dependency injection on the domain object. Also bypasses 
+     * caching (if any), that is each call to this method creates a new unique instance.
+     * </p>
+     * 
+     * @param viewModelPojo domain object
+     * @return  
      */
-    ObjectAdapter specificationForViewModel(final Object viewModelPojo);
+    ObjectAdapter disposableAdapterForViewModel(Object viewModelPojo);
+    
+    ObjectSpecification specificationForViewModel(Object viewModelPojo);
 
     ObjectAdapter adapterForViewModel(
             final Object viewModelPojo, 
@@ -97,7 +105,12 @@ public interface ObjectAdapterProvider {
         }
 
         @Programmatic
-        default ObjectAdapter specificationForViewModel(final Object viewModelPojo) {
+        default ObjectAdapter disposableAdapterForViewModel(final Object viewModelPojo) {
+            return getObjectAdapterProvider().disposableAdapterForViewModel(viewModelPojo);
+        }
+        
+        @Programmatic
+        default ObjectSpecification specificationForViewModel(Object viewModelPojo) {
             return getObjectAdapterProvider().specificationForViewModel(viewModelPojo);
         }
 
@@ -116,6 +129,9 @@ public interface ObjectAdapterProvider {
     }
 
 
+   
+
+
     
     
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetDeclarativeInitializingAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetDeclarativeInitializingAbstract.java
index 2b47acd..97cc65e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetDeclarativeInitializingAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetDeclarativeInitializingAbstract.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.facets.object.recreatable;
 
 import java.util.List;
 import java.util.Set;
+import java.util.UUID;
 
 import org.apache.isis.applib.services.urlencoding.UrlEncodingService;
 import org.apache.isis.commons.internal.memento._Mementos;
@@ -97,7 +98,7 @@ extends RecreatableObjectFacetAbstract {
 
         final _Mementos.Memento memento = _Mementos.create(codec, serializer);
 
-        final ObjectAdapter ownerAdapter = adapterProvider.specificationForViewModel(viewModelPojo);
+        final ObjectAdapter ownerAdapter = adapterProvider.disposableAdapterForViewModel(viewModelPojo);
         final ObjectSpecification spec = ownerAdapter.getSpecification();
         
         final List<OneToOneAssociation> properties = spec.getProperties(Contributed.EXCLUDED);
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 a9535a6..5ebfe1f 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
@@ -19,13 +19,16 @@
 package org.apache.isis.core.runtime.system.persistence.adaptermanager;
 
 import java.util.List;
+import java.util.Objects;
 import java.util.UUID;
 import java.util.function.Function;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.isis.commons.internal.functions._Predicates;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.ensure.Ensure;
 import org.apache.isis.core.commons.ensure.IsisAssertException;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
@@ -66,6 +69,7 @@ public class ObjectAdapterContext {
     
     private final PojoAdapterHashMap pojoAdapterMap = new PojoAdapterHashMap();
     private final OidAdapterHashMap oidAdapterMap = new OidAdapterHashMap();
+    private final OidAdapterHashMap oidAdapterMap2 = new OidAdapterHashMap();
     private final PersistenceSession persistenceSession; 
     private final ServicesInjector servicesInjector;
     private final SpecificationLoader specificationLoader;
@@ -100,6 +104,7 @@ public class ObjectAdapterContext {
     public void open() {
         oidAdapterMap.open();
         pojoAdapterMap.open();
+        oidAdapterMap2.open();
         initServices();
     }
     
@@ -107,6 +112,7 @@ public class ObjectAdapterContext {
         
         try {
             oidAdapterMap.close();
+            oidAdapterMap2.close();
         } catch(final Throwable ex) {
             // ignore
             LOG.error("close: oidAdapterMap#close() failed; continuing to avoid memory leakage");
@@ -120,22 +126,45 @@ public class ObjectAdapterContext {
         }
     }
     
-    // -- CACHING
+    // -- CACHING DEPR.
 
     @Deprecated // don't expose caching
     protected ObjectAdapter lookupAdapterByPojo(Object pojo) {
-        return pojoAdapterMap.getAdapter(pojo);
+        final ObjectAdapter adapter = pojoAdapterMap.getAdapter(pojo);
+        if(adapter!=null) {
+            Oid y = adapter.getOid();
+            Objects.requireNonNull(y);
+            
+            Oid x = objectAdapterProviderMixin.oidFor(pojo);
+            Objects.requireNonNull(x);
+            
+            //FIXME[ISIS-1976] oids must match
+            //Ensure.ensureThatArg(x, _Predicates.equalTo(y), ()->String.format("x: %s\ny: %s", ""+x, ""+y));
+        }
+        return adapter;
     }
     
     private void putPojo(Object pojo, ObjectAdapter adapter) {
+        
+        Oid x = objectAdapterProviderMixin.oidFor(pojo);
+        Oid y = adapter.getOid();
+        Objects.requireNonNull(y);
+        
+        //FIXME[ISIS-1976] oids must match
+        //Ensure.ensureThatArg(x, _Predicates.equalTo(y), ()->String.format("x: %s\ny: %s", ""+x, ""+y));
+        
+        oidAdapterMap2.add(adapter.getOid(), adapter);
         pojoAdapterMap.add(adapter.getObject(), adapter);
     }
     
     private void removePojo(ObjectAdapter adapter) {
+        Oid y = adapter.getOid();
+        Objects.requireNonNull(y);
+        oidAdapterMap2.remove(y);
         pojoAdapterMap.remove(adapter);
     }
     
-    // --
+    // -- CACHING
     
     @Deprecated // don't expose caching
     public boolean containsAdapterForPojo(Object pojo) {
@@ -315,28 +344,15 @@ public class ObjectAdapterContext {
         oidAdapterMap.add(adapter.getOid(), adapter);
     }
     
-    public ObjectAdapter specificationForViewModel(Object viewModelPojo) {
-        //FIXME[ISIS-1976]
-        // this is horrible, but there's a catch-22 here...
-        // we need an adapter in order to query the state of the object via the metamodel, on the other hand
-        // we can't create an adapter without the identifier, which is what we're trying to derive
-        // so... we create a temporary transient adapter, use it to wrap this adapter and interrogate this pojo,
-        // then throw away that adapter (remove from the adapter map)
-        final boolean[] createdTemporaryAdapter = {false};
-        final ObjectAdapter viewModelAdapter = adapterForViewModel(
-                viewModelPojo, 
-                (ObjectSpecId objectSpecId)->{
-                    createdTemporaryAdapter[0] = true;
-                    return RootOid.create(objectSpecId, UUID.randomUUID().toString()); });
-    
-        //final ObjectSpecification spec = viewModelAdapter.getSpecification();
-        
-        if(createdTemporaryAdapter[0]) {
-            adapterManagerMixin.removeAdapterFromCache(viewModelAdapter);
-        }
-        return viewModelAdapter;
+    public ObjectAdapter disposableAdapterForViewModel(Object viewModelPojo) {
+            final ObjectSpecification objectSpecification = 
+                    specificationLoader.loadSpecification(viewModelPojo.getClass());
+            final ObjectSpecId objectSpecId = objectSpecification.getSpecId();
+            final RootOid newRootOid = RootOid.create(objectSpecId, UUID.randomUUID().toString());
+            final ObjectAdapter createdAdapter = adapterManagerMixin.createRootOrAggregatedAdapter(newRootOid, viewModelPojo);
+            return createdAdapter;
     }
-
+    
     public ObjectAdapter adapterForViewModel(Object viewModelPojo, Function<ObjectSpecId, RootOid> rootOidFactory) {
         ObjectAdapter viewModelAdapter = adapterManagerMixin.lookupAdapterFor(viewModelPojo);
         if(viewModelAdapter == null) {
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
index f88f5f8..e60d247 100644
--- 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
@@ -178,6 +178,36 @@ class ObjectAdapterContext_AdapterManager {
         return adapter;
     }
     
+    ObjectAdapter injectServices(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();
+
+        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;
+        }
+
+        // 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) {
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
index ba820e3..77545ab 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
@@ -116,8 +116,15 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
     }
 
     @Override
-    public ObjectAdapter specificationForViewModel(Object viewModelPojo) {
-        return objectAdapterContext.specificationForViewModel(viewModelPojo);
+    public ObjectSpecification specificationForViewModel(Object viewModelPojo) {
+        final ObjectSpecification objectSpecification = 
+                specificationLoader.loadSpecification(viewModelPojo.getClass());
+        return objectSpecification;
+    }
+    
+    @Override
+    public ObjectAdapter disposableAdapterForViewModel(Object viewModelPojo) {
+        return objectAdapterContext.disposableAdapterForViewModel(viewModelPojo);
     }
 
     @Override