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:13:03 UTC
[isis] 16/18: ISIS-1976: lazy initialize OAs for services
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