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 2022/08/11 13:29:25 UTC
[isis] branch master updated: ISIS-3119: refactors IdStringifierLookupService into IdStringifierService
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 8a39779183 ISIS-3119: refactors IdStringifierLookupService into IdStringifierService
8a39779183 is described below
commit 8a39779183e51ad4ac23155e39c97198af14a7c9
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Aug 11 15:29:18 2022 +0200
ISIS-3119: refactors IdStringifierLookupService into
IdStringifierService
- that is, with a more focused responsibility (for internal use by
entity facets)
---
.../applib/services/bookmark/IdStringifier.java | 2 +-
.../isis/core/runtime/IsisModuleCoreRuntime.java | 4 +-
...ookupService.java => IdStringifierService.java} | 58 ++++++++++++++--------
.../metamodel/facets/entity/JdoEntityFacet.java | 20 ++------
.../jpa/integration/entity/JpaEntityFacet.java | 25 +++-------
5 files changed, 50 insertions(+), 59 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/IdStringifier.java b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/IdStringifier.java
index f8ad36560c..c585083f2f 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/IdStringifier.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/IdStringifier.java
@@ -44,7 +44,7 @@ import lombok.val;
* An example of such is the JPA implementation of the <code>commandlog</code> extension.
* </p>
*
- * @since 2.x {@index}
+ * @since 2.0 {@index}
*/
public interface IdStringifier<T> {
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/IsisModuleCoreRuntime.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/IsisModuleCoreRuntime.java
index 063ea58bd9..dd5a2de831 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/IsisModuleCoreRuntime.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/IsisModuleCoreRuntime.java
@@ -25,7 +25,7 @@ import org.apache.isis.core.interaction.IsisModuleCoreInteraction;
import org.apache.isis.core.metamodel.IsisModuleCoreMetamodel;
import org.apache.isis.core.runtime.events.MetamodelEventService;
import org.apache.isis.core.runtime.events.TransactionEventEmitter;
-import org.apache.isis.core.runtime.idstringifier.IdStringifierLookupService;
+import org.apache.isis.core.runtime.idstringifier.IdStringifierService;
import org.apache.isis.core.transaction.IsisModuleCoreTransaction;
import org.apache.isis.valuetypes.jodatime.integration.IsisModuleValJodatimeIntegration;
@@ -42,7 +42,7 @@ import org.apache.isis.valuetypes.jodatime.integration.IsisModuleValJodatimeInte
// @Service's
MetamodelEventService.class,
TransactionEventEmitter.class,
- IdStringifierLookupService.class,
+ IdStringifierService.class,
// @Configuration's
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierLookupService.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierService.java
similarity index 63%
rename from core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierLookupService.java
rename to core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierService.java
index 4bb0cebd6a..8a27baccef 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierLookupService.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierService.java
@@ -35,9 +35,11 @@ import org.springframework.stereotype.Service;
import org.springframework.util.ClassUtils;
import org.apache.isis.applib.annotation.PriorityPrecedence;
+import org.apache.isis.applib.annotation.ValueSemantics;
import org.apache.isis.applib.services.bookmark.IdStringifier;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.base._Casts;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.runtime.IsisModuleCoreRuntime;
import lombok.NonNull;
@@ -46,24 +48,27 @@ import lombok.val;
/**
* Convenience service that looks up (and caches) the {@link IdStringifier}
* available for a given value class, and optionally the class of the owning entity.
- *
* <p>
- * This is intended for framework use, there is little reason to call it or override it.
- * </p>
+ * This is intended for framework use, there is little reason to call it or override it.
+ *
+ * @implNote yet does not support per member ValueSemantics selection;
+ * future work would look for {@link ValueSemantics} annotations on primary key members and
+ * would then honor {@link ValueSemantics#provider()} attribute,
+ * to narrow the {@link IdStringifier} search
*
* @since 2.0
*/
@Service
-@Named(IsisModuleCoreRuntime.NAMESPACE + ".IdStringifierLookupService")
+@Named(IsisModuleCoreRuntime.NAMESPACE + ".IdStringifierService")
@Priority(PriorityPrecedence.MIDPOINT)
@Qualifier("Default")
-public class IdStringifierLookupService {
+public class IdStringifierService {
private final Can<IdStringifier<?>> idStringifiers;
private final Map<Class<?>, IdStringifier<?>> stringifierByClass = new ConcurrentHashMap<>();
@Inject
- public IdStringifierLookupService(
+ public IdStringifierService(
final List<IdStringifier<?>> idStringifiers,
final Optional<IdStringifier<Serializable>> idStringifierForSerializableIfAny) {
// IdStringifierForSerializable is enforced to go last, so any custom IdStringifier(s)
@@ -77,22 +82,33 @@ public class IdStringifierLookupService {
this.idStringifiers = Can.ofCollection(idStringifiers);
}
- public <T> IdStringifier<T> lookupElseFail(final Class<T> candidateValueClass) {
- val idStringifier = stringifierByClass.computeIfAbsent(candidateValueClass, aClass -> {
- for (val candidateStringifier : idStringifiers) {
- if (handles(candidateStringifier, candidateValueClass)) {
- return candidateStringifier;
- }
- }
- return null;
- });
- return Optional.<IdStringifier<T>>ofNullable(_Casts.uncheckedCast(idStringifier))
- .orElseThrow(() -> new IllegalStateException(
- String.format("Could not locate an IdStringifier to handle '%s'",
- candidateValueClass)));
+ public <T> String enstringPrimaryKey(final @NonNull Class<T> primaryKeyType, final @NonNull Object primaryKey) {
+ val idStringifier = lookupElseFail(ClassUtils.resolvePrimitiveIfNecessary(primaryKeyType));
+ return idStringifier.enstring(_Casts.uncheckedCast(primaryKey));
+ }
+
+ public <T> T destringPrimaryKey(
+ final @NonNull Class<T> primaryKeyType,
+ final @NonNull Class<?> entityClass,
+ final @NonNull String stringifiedId) {
+ val idStringifier = lookupElseFail(ClassUtils.resolvePrimitiveIfNecessary(primaryKeyType));
+ @SuppressWarnings("unchecked")
+ val primaryKey = _Casts.castTo(IdStringifier.SupportingTargetEntityClass.class, idStringifier)
+ .map(stringifier->stringifier.destring(stringifiedId, entityClass))
+ .orElseGet(()->idStringifier.destring(stringifiedId));
+ return _Casts.uncheckedCast(primaryKey);
}
- public <T> Optional<IdStringifier<T>> lookup(final Class<T> candidateValueClass) {
+ // -- HELPER
+
+ private <T> IdStringifier<T> lookupElseFail(final Class<T> candidateValueClass) {
+ return lookup(candidateValueClass)
+ .orElseThrow(() -> _Exceptions.noSuchElement(
+ "Could not locate an IdStringifier to handle '%s'",
+ candidateValueClass));
+ }
+
+ private <T> Optional<IdStringifier<T>> lookup(final Class<T> candidateValueClass) {
val idStringifier = stringifierByClass.computeIfAbsent(candidateValueClass, aClass -> {
for (val candidateStringifier : idStringifiers) {
if (handles(candidateStringifier, candidateValueClass)) {
@@ -104,8 +120,6 @@ public class IdStringifierLookupService {
return Optional.ofNullable(_Casts.uncheckedCast(idStringifier));
}
- // -- HELPER
-
private boolean handles(final IdStringifier<?> idStringifier, final @NonNull Class<?> candidateValueClass) {
return idStringifier.getCorrespondingClass()
.isAssignableFrom(ClassUtils.resolvePrimitiveIfNecessary(candidateValueClass));
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
index 45f987cd2e..256407fdb5 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
@@ -37,7 +37,6 @@ import org.apache.isis.applib.query.AllInstancesQuery;
import org.apache.isis.applib.query.NamedQuery;
import org.apache.isis.applib.query.Query;
import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.bookmark.IdStringifier;
import org.apache.isis.applib.services.exceprecog.Category;
import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerService;
import org.apache.isis.applib.services.repository.EntityState;
@@ -45,7 +44,6 @@ import org.apache.isis.applib.services.xactn.TransactionService;
import org.apache.isis.applib.services.xactn.TransactionalProcessor;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.assertions._Assert;
-import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.commons.internal.base._NullSafe;
import org.apache.isis.commons.internal.collections._Maps;
import org.apache.isis.commons.internal.debug._Debug;
@@ -59,7 +57,7 @@ import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
import org.apache.isis.core.metamodel.services.objectlifecycle.ObjectLifecyclePublisher;
import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.runtime.idstringifier.IdStringifierLookupService;
+import org.apache.isis.core.runtime.idstringifier.IdStringifierService;
import org.apache.isis.persistence.jdo.datanucleus.entities.DnEntityStateProvider;
import org.apache.isis.persistence.jdo.metamodel.facets.object.persistencecapable.JdoPersistenceCapableFacetFactory;
import org.apache.isis.persistence.jdo.provider.entities.JdoFacetContext;
@@ -84,7 +82,7 @@ implements EntityFacet {
@Inject private ObjectManager objectManager;
@Inject private ExceptionRecognizerService exceptionRecognizerService;
@Inject private JdoFacetContext jdoFacetContext;
- @Inject private IdStringifierLookupService idStringifierLookupService;
+ @Inject private IdStringifierService idStringifierService;
private final Class<?> entityClass;
@@ -135,11 +133,7 @@ implements EntityFacet {
pojo.getClass().getName());
}
-
- val primaryKeyType = primaryKey.getClass();
- val idStringifier = _Casts.<IdStringifier<Object>>uncheckedCast(idStringifierLookupService.lookupElseFail(primaryKeyType));
-
- return idStringifier.enstring(primaryKey);
+ return idStringifierService.enstringPrimaryKey(primaryKeyTypeFor(entityClass), primaryKey);
}
@@ -153,12 +147,8 @@ implements EntityFacet {
try {
val persistenceManager = getPersistenceManager();
- val primaryKeyType = primaryKeyTypeFor(entityClass);
-
- val idStringifier = idStringifierLookupService.lookupElseFail(primaryKeyType);
- val primaryKey = _Casts.castTo(IdStringifier.SupportingTargetEntityClass.class, idStringifier)
- .map(stringifier->stringifier.destring(bookmark.getIdentifier(), entityClass))
- .orElseGet(()->idStringifier.destring(bookmark.getIdentifier()));
+ val primaryKey = idStringifierService
+ .destringPrimaryKey(primaryKeyTypeFor(entityClass), entityClass, bookmark.getIdentifier());
val fetchPlan = persistenceManager.getFetchPlan();
fetchPlan.addGroup(FetchGroup.DEFAULT);
diff --git a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java b/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java
index fa7097205b..5a64c89efc 100644
--- a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java
+++ b/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java
@@ -34,7 +34,6 @@ import org.apache.isis.applib.query.AllInstancesQuery;
import org.apache.isis.applib.query.NamedQuery;
import org.apache.isis.applib.query.Query;
import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.bookmark.IdStringifier;
import org.apache.isis.applib.services.registry.ServiceRegistry;
import org.apache.isis.applib.services.repository.EntityState;
import org.apache.isis.commons.collections.Can;
@@ -47,7 +46,7 @@ import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.runtime.idstringifier.IdStringifierLookupService;
+import org.apache.isis.core.runtime.idstringifier.IdStringifierService;
import lombok.NonNull;
import lombok.val;
@@ -60,7 +59,7 @@ public class JpaEntityFacet
private final Class<?> entityClass;
private final ServiceRegistry serviceRegistry;
- private final IdStringifierLookupService idStringifierLookupService;
+ private final IdStringifierService idStringifierService;
protected JpaEntityFacet(
final FacetHolder holder,
@@ -70,7 +69,7 @@ public class JpaEntityFacet
super(EntityFacet.class, holder, Precedence.HIGH);
this.entityClass = entityClass;
this.serviceRegistry = serviceRegistry;
- this.idStringifierLookupService = serviceRegistry.lookupServiceElseFail(IdStringifierLookupService.class);
+ this.idStringifierService = serviceRegistry.lookupServiceElseFail(IdStringifierService.class);
}
// -- ENTITY FACET
@@ -101,17 +100,7 @@ public class JpaEntityFacet
pojo.getClass().getName());
}
- val primaryKeyType = getPrimaryKeyType();
- return identifierFor(primaryKeyType, _Casts.uncheckedCast(primaryKey));
- }
-
- private <T> String identifierFor(final Class<T> primaryKeyType, final T primaryKey) {
- val stringifier = lookupIdStringifier(primaryKeyType);
- return stringifier.enstring(primaryKey);
- }
-
- private <T> IdStringifier<T> lookupIdStringifier(final Class<T> primaryKeyType) {
- return _Casts.uncheckedCast(idStringifierLookupService.lookupElseFail(primaryKeyType));
+ return idStringifierService.enstringPrimaryKey(getPrimaryKeyType(), primaryKey);
}
@Override
@@ -120,10 +109,8 @@ public class JpaEntityFacet
log.debug("fetchEntity; bookmark={}", bookmark);
- val idStringifier = lookupIdStringifier(getPrimaryKeyType());
- val primaryKey = _Casts.castTo(IdStringifier.SupportingTargetEntityClass.class, idStringifier)
- .map(stringifier->stringifier.destring(bookmark.getIdentifier(), entityClass))
- .orElseGet(()->idStringifier.destring(bookmark.getIdentifier()));
+ val primaryKey = idStringifierService
+ .destringPrimaryKey(getPrimaryKeyType(), entityClass, bookmark.getIdentifier());
val entityManager = getEntityManager();
val entityPojo = entityManager.find(entityClass, primaryKey);