You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/03/02 07:17:08 UTC

[isis] branch master updated (53d9949 -> 20c99fa)

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

ahuber pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git.


    from 53d9949  Bump approvaltests from 10.0.0 to 10.0.1
     new a113889  ISIS-2553: place initial deprecation markers
     new fff9628  ISIS-2553: TypeIdentifier: add namespace related getters
     new 0fe22fb  ISIS-2553: using LogicalType instead of ObjectSpedId (1st iteration)
     new 8be18b5  ISIS-2553: using LogicalType instead of ObjectSpecId (2nd iteration)
     new af65382  ISIS-2553: using LogicalType instead of ObjectSpecId (3rd iteration)
     new a088d39  ISIS-2553: using LogicalType instead of ObjectSpecId (4th iteration)
     new a82d59b  ISIS-2553: test fixes
     new 3f1c899  ISIS-2553: using LogicalType instead of ObjectSpecId (5th iteration)
     new ea93a64  ISIS-2553: remove ObjectSpecId
     new a2aae4a  ISIS-2553: improve some java-doc
     new 20c99fa  ISIS-2553: prepare for merge

The 11 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:
 .../java/org/apache/isis/applib/Identifier.java    | 34 +++++----
 .../org/apache/isis/applib/id/HasLogicalType.java  | 15 ++--
 .../id/{TypeIdentifier.java => LogicalType.java}   | 88 ++++++++++++++++++----
 .../isis/applib/services/bookmark/Bookmark.java    | 35 +++++----
 .../org/apache/isis/applib/IdentifierTests.java    | 10 +--
 .../isis/applib/events/InteractionEventTest.java   |  4 +-
 ...ypeIdentifierTest.java => LogicalTypeTest.java} | 25 ++++--
 .../applib/id/LogicalTypeTest_valueSemantics.java  | 21 ++++--
 .../isis/core/metamodel/adapter/oid/Oid.java       | 33 ++++----
 .../core/metamodel/adapter/oid/Oid_Marshaller.java |  6 +-
 .../isis/core/metamodel/adapter/oid/Oid_Root.java  | 55 +++++---------
 .../isis/core/metamodel/adapter/oid/Oid_Value.java |  3 +-
 .../isis/core/metamodel/adapter/oid/RootOid.java   |  2 +-
 .../isis/core/metamodel/facetapi/FeatureType.java  | 18 ++---
 .../isis/core/metamodel/facets/FacetedMethod.java  |  8 +-
 .../metamodel/facets/FacetedMethodParameter.java   |  8 +-
 .../actions/action/invocation/CommandUtil.java     |  2 +-
 .../ViewModelSemanticCheckingFacetFactory.java     | 10 +--
 .../DomainObjectAnnotationFacetFactory.java        | 24 +++---
 .../facets/object/grid/GridFacetDefault.java       |  4 +-
 .../mixin/MetaModelValidatorForMixinTypes.java     |  6 +-
 .../object/objectspecid/ObjectSpecIdFacet.java     |  3 +-
 .../objectspecid/ObjectSpecIdFacetAbstract.java    | 22 ++----
 .../ObjectSpecIdFacetOnStandaloneList.java         |  3 +-
 .../identify/ObjectIdentifier_builtinHandlers.java |  8 +-
 .../load/ObjectLoader_builtinHandlers.java         |  2 +-
 .../isis/core/metamodel/services/ServiceUtil.java  |  2 +-
 .../services/appfeat/ApplicationFeatureId.java     |  8 +-
 .../ApplicationFeatureRepositoryDefault.java       |  2 +-
 .../metamodel/MetaModelServiceDefault.java         | 18 ++---
 .../title/TitlesAndTranslationsValidator.java      | 16 ++--
 .../isis/core/metamodel/spec/ManagedObjects.java   |  9 +--
 .../isis/core/metamodel/spec/ObjectSpecId.java     | 65 ----------------
 .../core/metamodel/spec/ObjectSpecification.java   | 23 +-----
 .../core/metamodel/spec/feature/ObjectAction.java  |  4 +-
 .../spec/feature/OneToOneAssociation.java          |  2 +-
 ...ClassResolver.java => LogicalTypeResolver.java} |  6 +-
 ...efault.java => LogicalTypeResolverDefault.java} | 14 ++--
 .../metamodel/specloader/SpecificationLoader.java  | 49 ++++++++----
 .../specloader/SpecificationLoaderDefault.java     | 33 ++++----
 .../specloader/specimpl/ObjectActionMixedIn.java   |  6 +-
 .../specimpl/ObjectSpecificationAbstract.java      | 26 +++----
 .../specimpl/OneToManyAssociationMixedIn.java      |  6 +-
 .../specimpl/OneToOneAssociationMixedIn.java       |  6 +-
 .../specimpl/dflt/ObjectSpecificationDefault.java  |  2 +-
 .../adapter/oid/LogicalTypeTestFactory.java        | 21 +++---
 .../adapter/oid/OidMarshallerTest_marshall.java    |  4 +-
 .../oid/OidMarshallerTest_roundtripping.java       |  6 +-
 .../adapter/oid/OidMarshallerTest_unmarshal.java   |  8 +-
 .../core/metamodel/adapter/oid/OidVersionTest.java | 18 ++---
 ...dDefaultTest_valueSemantics_whenPersistent.java | 14 ++--
 .../metamodel/adapter/oid/RootOidTest_create.java  |  9 +--
 .../facetapi/FeatureTypeTest_identifierFor.java    |  6 +-
 .../facets/AbstractFacetFactoryJUnit4TestCase.java |  4 +-
 .../metamodel/facets/AbstractFacetFactoryTest.java |  4 +-
 ...nEventHelperTest_newActionInteractionEvent.java |  8 +-
 ...HelperTest_newCollectionDomainEvent_forAdd.java |  8 +-
 ...perTest_newCollectionDomainEvent_forRemove.java |  8 +-
 ...HelperTest_newPropertyDomainEvent_forClear.java |  6 +-
 ...elperTest_newPropertyDomainEvent_forModify.java |  6 +-
 .../DomainObjectAnnotationFacetFactoryTest.java    |  3 +-
 .../ObjectTypeAnnotationFacetFactoryTest.java      |  3 +-
 .../facets/object/mixin/MixinIntendedAs.java       |  4 +-
 ...SpecIdFacetDerivedFromClassNameFactoryTest.java |  3 +-
 .../metamodel/id/TypeIdentifierTestFactory.java    |  6 +-
 .../spec/ObjectSpecIdTest_constructor.java         | 43 -----------
 .../specloader/SpecificationCacheDefaultTest.java  | 18 +++--
 .../testspec/ObjectSpecificationStub.java          | 24 +++---
 .../isis/core/runtime/memento/ObjectMemento.java   | 18 ++---
 .../runtime/memento/ObjectMementoCollection.java   |  7 +-
 .../runtime/memento/ObjectMementoForEmpty.java     | 10 +--
 .../core/runtime/memento/ObjectMementoService.java |  6 +-
 .../bookmarks/BookmarkServiceDefault.java          |  5 +-
 .../command/CommandExecutorServiceDefault.java     |  2 +-
 .../menubars/bootstrap3/MenuBarsServiceBS3.java    |  2 +-
 .../AbstractRoleAndPermissionsFixtureScript.java   |  4 +-
 .../component/FullCalendarWithEventHandling.java   |  2 +-
 .../metamodel/facets/entity/JdoEntityFacet.java    |  2 +-
 .../object/query/VisitorForClauseAbstract.java     |  7 +-
 .../facets/object/query/VisitorForFromClause.java  |  7 +-
 .../object/query/VisitorForVariablesClause.java    |  7 +-
 ...JdoDiscriminatorAnnotationFacetFactoryTest.java |  3 +-
 .../object/version/TypeIdentifierTestFactory.java  |  6 +-
 .../testing/AbstractFacetFactoryTest.java          |  4 +-
 .../testdomain/domainmodel/SpecLoaderTest.java     |  6 +-
 .../testdomain/rest/DomainObjectResourceTest.java  |  4 +-
 .../shiro/authorization/AuthorizorShiro.java       |  2 +-
 .../security/shiro/TypeIdentifierTestFactory.java  | 10 +--
 .../common/model/mementos/ActionMemento.java       | 21 +++---
 .../common/model/menu/MenuUiModelProvider.java     |  4 +-
 .../domainobjects/DomainObjectReprRenderer.java    | 10 +--
 .../rendering/domainobjects/JsonValueEncoder.java  | 36 ++++-----
 .../AbstractTypeMemberReprRenderer.java            |  2 +-
 .../domaintypes/ActionDescriptionReprRenderer.java |  2 +-
 .../ActionParameterDescriptionReprRenderer.java    |  2 +-
 .../CollectionDescriptionReprRenderer.java         |  2 +-
 .../domaintypes/DomainTypeReprRenderer.java        | 10 +--
 .../PropertyDescriptionReprRenderer.java           |  2 +-
 .../domaintypes/TypeListReprRenderer.java          |  2 +-
 ...entNegotiationServiceForRestfulObjectsV1_0.java |  4 +-
 .../service/swagger/internal/Generation.java       |  2 +-
 .../JsonValueEncoderTest_appendValueAndFormat.java | 13 ++--
 .../JsonValueEncoderTest_asAdapter.java            | 12 +--
 .../JsonValueEncoderTest_asObject.java             |  8 +-
 .../resources/DomainObjectResourceServerside.java  |  6 +-
 .../resources/DomainTypeResourceServerside.java    | 21 +++---
 .../viewer/wicket/model/links/LinkAndLabel.java    |  8 +-
 .../wicket/model/mementos/CollectionMemento.java   | 19 ++---
 .../wicket/model/mementos/PropertyMemento.java     | 36 +++++----
 .../model/models/BookmarkTreeNodeComparator.java   |  4 +-
 .../wicket/model/models/ManagedObjectModel.java    | 22 +++---
 .../wicket/model/models/PageParameterUtil.java     |  8 +-
 .../viewer/wicket/model/models/ScalarModel.java    |  7 +-
 .../model/models/ScalarModelWithMultiPending.java  |  9 +--
 .../actions/ActionParametersFormPanel.java         |  2 +-
 .../bookmarkedpages/BookmarkedPagesPanel.java      |  4 +-
 .../CollectionContentsAsAjaxTablePanel.java        |  2 +-
 .../scalars/ScalarPanelSelectAbstract.java         |  4 +-
 .../StandaloneCollectionPanel.java                 |  4 +-
 .../linkandlabel/LinkAndLabelFactoryAbstract.java  |  2 +-
 .../ui/components/widgets/select2/ChoiceExt.java   |  8 +-
 .../ui/components/widgets/select2/Select2.java     |  6 +-
 .../widgets/select2/Select2ChoiceExt.java          | 16 ++--
 .../widgets/select2/Select2MultiChoiceExt.java     | 15 ++--
 .../ObjectAdapterMementoProviderAbstract.java      |  6 +-
 .../viewer/wicket/ui/pages/entity/EntityPage.java  |  2 +-
 ...tAdapterMementoProviderForValueChoicesTest.java | 20 +++--
 .../integration/ConverterForObjectAdapter.java     |  3 +-
 .../mementos/ObjectMementoServiceWicket.java       | 22 +++---
 .../viewer/services/mementos/ObjectMementoWkt.java | 64 ++++++++--------
 130 files changed, 735 insertions(+), 811 deletions(-)
 copy commons/src/main/java/org/apache/isis/commons/having/HasUniqueId.java => api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java (77%)
 rename api/applib/src/main/java/org/apache/isis/applib/id/{TypeIdentifier.java => LogicalType.java} (67%)
 rename api/applib/src/test/java/org/apache/isis/applib/id/{TypeIdentifierTest.java => LogicalTypeTest.java} (67%)
 rename core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_valueSemantics.java => api/applib/src/test/java/org/apache/isis/applib/id/LogicalTypeTest_valueSemantics.java (58%)
 delete mode 100644 core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecId.java
 rename core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/{SpecIdToClassResolver.java => LogicalTypeResolver.java} (87%)
 rename core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/{SpecIdToClassResolverDefault.java => LogicalTypeResolverDefault.java} (77%)
 copy security/shiro/src/test/java/org/apache/isis/security/shiro/TypeIdentifierTestFactory.java => core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/LogicalTypeTestFactory.java (65%)
 delete mode 100644 core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_constructor.java


[isis] 04/11: ISIS-2553: using LogicalType instead of ObjectSpecId (2nd iteration)

Posted by ah...@apache.org.
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

commit 8be18b554c26022acdcf8579b072e3acf502c92d
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Mar 1 18:53:17 2021 +0100

    ISIS-2553: using LogicalType instead of ObjectSpecId (2nd iteration)
---
 .../org/apache/isis/applib/id/HasLogicalType.java  | 20 ++++++++++--
 .../isis/core/metamodel/facets/FacetedMethod.java  |  6 ++--
 .../metamodel/facets/FacetedMethodParameter.java   |  6 ++--
 .../actions/action/invocation/CommandUtil.java     |  2 +-
 .../DomainObjectAnnotationFacetFactory.java        | 20 ++++++------
 .../facets/object/grid/GridFacetDefault.java       |  4 +--
 .../load/ObjectLoader_builtinHandlers.java         |  2 +-
 .../isis/core/metamodel/services/ServiceUtil.java  |  2 +-
 .../ApplicationFeatureRepositoryDefault.java       |  2 +-
 .../title/TitlesAndTranslationsValidator.java      | 10 +++---
 .../isis/core/metamodel/spec/ManagedObjects.java   |  8 ++---
 .../core/metamodel/spec/ObjectSpecification.java   | 34 +++-----------------
 .../core/metamodel/spec/feature/ObjectAction.java  |  4 +--
 .../spec/feature/OneToOneAssociation.java          |  2 +-
 .../specloader/specimpl/ObjectActionMixedIn.java   |  2 +-
 .../specimpl/ObjectSpecificationAbstract.java      | 19 +++++-------
 .../specimpl/OneToManyAssociationMixedIn.java      |  2 +-
 .../specimpl/OneToOneAssociationMixedIn.java       |  2 +-
 .../bookmarks/BookmarkServiceDefault.java          |  2 +-
 .../menubars/bootstrap3/MenuBarsServiceBS3.java    |  2 +-
 .../AbstractRoleAndPermissionsFixtureScript.java   |  4 +--
 .../testdomain/rest/DomainObjectResourceTest.java  |  4 +--
 .../common/model/mementos/ActionMemento.java       | 23 ++++++--------
 .../common/model/menu/MenuUiModelProvider.java     |  4 +--
 .../domainobjects/DomainObjectReprRenderer.java    |  3 +-
 .../rendering/domainobjects/JsonValueEncoder.java  | 36 +++++++++-------------
 .../AbstractTypeMemberReprRenderer.java            |  2 +-
 .../domaintypes/ActionDescriptionReprRenderer.java |  2 +-
 .../ActionParameterDescriptionReprRenderer.java    |  2 +-
 .../CollectionDescriptionReprRenderer.java         |  2 +-
 .../domaintypes/DomainTypeReprRenderer.java        | 10 +++---
 .../PropertyDescriptionReprRenderer.java           |  2 +-
 .../domaintypes/TypeListReprRenderer.java          |  2 +-
 ...entNegotiationServiceForRestfulObjectsV1_0.java |  4 +--
 .../JsonValueEncoderTest_appendValueAndFormat.java | 13 +++++---
 .../JsonValueEncoderTest_asAdapter.java            | 12 ++++----
 .../JsonValueEncoderTest_asObject.java             |  8 ++---
 .../wicket/model/mementos/CollectionMemento.java   | 17 +++++-----
 .../wicket/model/models/PageParameterUtil.java     |  8 +++--
 .../actions/ActionParametersFormPanel.java         |  2 +-
 .../CollectionContentsAsAjaxTablePanel.java        |  2 +-
 .../StandaloneCollectionPanel.java                 |  4 +--
 .../linkandlabel/LinkAndLabelFactoryAbstract.java  |  2 +-
 .../viewer/wicket/ui/pages/entity/EntityPage.java  |  2 +-
 44 files changed, 143 insertions(+), 178 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java b/api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java
index 5e0523a..d840a16 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java
@@ -18,15 +18,31 @@
  */
 package org.apache.isis.applib.id;
 
+import org.apache.isis.applib.annotation.DomainObject;
+
 /**
  * @since 2.0 {@index}
  */
 public interface HasLogicalType {
 
     LogicalType getLogicalType();
-    
+
+    /**
+     * Returns the (unique) logical-type-name, as per the {@link ObjectSpecIdFacet}.
+     *
+     * <p>
+     * This will typically be the value of the {@link DomainObject#objectType()} annotation attribute.
+     * If none has been specified then will default to the fully qualified class name (with
+     * {@link ClassSubstitutorRegistry class name substituted} if necessary to allow for runtime 
+     * bytecode enhancement.
+     *
+     * <p> 
+     * TODO[2553] ... no longer true
+     * The {@link ObjectSpecification} can be retrieved using 
+     * {@link SpecificationLoader#lookupBySpecIdElseLoad(String)}}.
+     */
     default String getLogicalTypeName() {
         return getLogicalType().getLogicalTypeName();
     }
-    
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethod.java
index 4de5a69..215ba02 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethod.java
@@ -169,11 +169,11 @@ public class FacetedMethod extends TypedHolderDefault implements IdentifiedHolde
         this.owningType = declaringType;
         this.method = method;
         
-        val typeIdentifier = LogicalType.lazy(
+        val logicalType = LogicalType.lazy(
                 declaringType,
-                ()->getSpecificationLoader().loadSpecification(declaringType).getSpecId().asString());
+                ()->getSpecificationLoader().loadSpecification(declaringType).getLogicalTypeName());
         
-        this.identifier = featureType.identifierFor(typeIdentifier, method);
+        this.identifier = featureType.identifierFor(logicalType, method);
         this.parameters = parameters;
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethodParameter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethodParameter.java
index 1f3f15d..814ec44 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethodParameter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethodParameter.java
@@ -41,12 +41,12 @@ implements IdentifiedHolder {
         
         super(featureType, type);
         
-        val typeIdentifier = LogicalType.lazy(
+        val logicalType = LogicalType.lazy(
                 declaringType,
-                ()->getSpecificationLoader().loadSpecification(declaringType).getSpecId().asString());
+                ()->getSpecificationLoader().loadSpecification(declaringType).getLogicalTypeName());
         
         // best we can do...
-        this.identifier = FeatureType.ACTION.identifierFor(typeIdentifier, method);
+        this.identifier = FeatureType.ACTION.identifierFor(logicalType, method);
     }
 
     @Override
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 3738678..0c3ecc9 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
@@ -80,7 +80,7 @@ public class CommandUtil {
 
     private static String logicalMemberIdentifierFor(
             final ObjectSpecification onType, final ObjectMember objectMember) {
-        final String objectType = onType.getSpecId().asString();
+        final String objectType = onType.getLogicalTypeName();
         final String localId = objectMember.getIdentifier().getMemberName();
         return objectType + "#" + localId;
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
index f43439e..a19bad6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
@@ -40,7 +40,6 @@ import org.apache.isis.applib.events.lifecycle.ObjectRemovingEvent;
 import org.apache.isis.applib.events.lifecycle.ObjectUpdatedEvent;
 import org.apache.isis.applib.events.lifecycle.ObjectUpdatingEvent;
 import org.apache.isis.applib.id.LogicalType;
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.commons.having.HasUniqueId;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.collections._Multimaps;
@@ -480,16 +479,16 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
     public void refineProgrammingModel(ProgrammingModel programmingModel) {
 
         if(getConfiguration().getCore().getMetaModel().getValidator().isEnsureUniqueObjectTypes()) {
-            addValidatorToEnsureUniqueObjectIds(programmingModel);
+            addValidatorToEnsureUniqueLogicalTypeNames(programmingModel);
         }
 
         programmingModel.addValidator(autoCompleteMethodInvalid);
         programmingModel.addValidator(mixinTypeValidator);
     }
 
-    private void addValidatorToEnsureUniqueObjectIds(ProgrammingModel pm) {
+    private void addValidatorToEnsureUniqueLogicalTypeNames(ProgrammingModel pm) {
 
-        final _Multimaps.ListMultimap<ObjectSpecId, ObjectSpecification> collidingSpecsById =
+        final _Multimaps.ListMultimap<String, ObjectSpecification> collidingSpecsByLogicalTypeName =
                 _Multimaps.newConcurrentListMultimap();
 
         final MetaModelValidatorVisiting.SummarizingVisitor ensureUniqueObjectIds =
@@ -497,15 +496,14 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
 
                     @Override
                     public boolean visit(ObjectSpecification objSpec, MetaModelValidator validator) {
-                        val specId = objSpec.getSpecId();
-                        collidingSpecsById.putElement(specId, objSpec);
+                        collidingSpecsByLogicalTypeName.putElement(objSpec.getLogicalTypeName() , objSpec);
                         return true;
                     }
 
                     @Override
                     public void summarize(MetaModelValidator validator) {
-                        for (val specId : collidingSpecsById.keySet()) {
-                            val collidingSpecs = collidingSpecsById.get(specId);
+                        for (val logicalTypeName : collidingSpecsByLogicalTypeName.keySet()) {
+                            val collidingSpecs = collidingSpecsByLogicalTypeName.get(logicalTypeName);
                             val isCollision = collidingSpecs.size()>1;
                             if(isCollision) {
                                 val csv = asCsv(collidingSpecs);
@@ -514,8 +512,8 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
                                     validator.onFailure(
                                             spec,
                                             spec.getIdentifier(),
-                                            "Object type '%s' mapped to multiple classes: %s",
-                                            specId.asString(),
+                                            "Logical-type-name (aka. object-type) '%s' mapped to multiple classes: %s",
+                                            logicalTypeName,
                                             csv);
                                 });
 
@@ -523,7 +521,7 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
                             }
                         }
                         // so can be revalidated again if necessary.
-                        collidingSpecsById.clear();
+                        collidingSpecsByLogicalTypeName.clear();
                     }
 
                     private String asCsv(final List<ObjectSpecification> specList) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
index b507d55..0e00bea 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
@@ -97,8 +97,8 @@ implements GridFacet {
                     "getGrid(adapter) was called passing an adapter (specId: %s), "
                     + "for which this GridFacet (specId: %s) is not responsible; "
                     + "indicates that some framework internals are wired up in a wrong way",
-                    objectAdapter.getSpecification().getSpecId().asString(),
-                    getSpecification().getSpecId().asString());
+                    objectAdapter.getSpecification().getLogicalTypeName(),
+                    getSpecification().getLogicalTypeName());
         }
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader_builtinHandlers.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader_builtinHandlers.java
index 4648a7e..abf5e70 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader_builtinHandlers.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader_builtinHandlers.java
@@ -90,7 +90,7 @@ final class ObjectLoader_builtinHandlers {
         public ManagedObject handle(ObjectLoader.Request objectLoadRequest) {
             
             val spec = objectLoadRequest.getObjectSpecification();
-            val beanName = spec.getSpecId().asString();
+            val beanName = spec.getLogicalTypeName();
             
             val servicePojo = metaModelContext.getServiceRegistry()
                 .lookupRegisteredBeanById(beanName)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServiceUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServiceUtil.java
index c895860..46c6375 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServiceUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServiceUtil.java
@@ -30,7 +30,7 @@ public final class ServiceUtil {
     public static String idOfSpec(final ObjectSpecification serviceSpec) {
         _Assert.assertEquals( 
                 serviceSpec.getManagedBeanName(), 
-                serviceSpec.getSpecId().asString());
+                serviceSpec.getLogicalTypeName());
         return serviceSpec.getManagedBeanName();
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
index c0cb69a..8174e00 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
@@ -137,7 +137,7 @@ public class ApplicationFeatureRepositoryDefault implements ApplicationFeatureRe
             return;
         }
 
-        final String specIdString = spec.getSpecId().asString();
+        final String specIdString = spec.getLogicalTypeName();
         final ApplicationFeatureId classFeatureId = ApplicationFeatureId.newClass(specIdString);
 
         // add class to our map
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/title/TitlesAndTranslationsValidator.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/title/TitlesAndTranslationsValidator.java
index 52557cd..33e854a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/title/TitlesAndTranslationsValidator.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/title/TitlesAndTranslationsValidator.java
@@ -121,8 +121,7 @@ public class TitlesAndTranslationsValidator extends MetaModelValidatorAbstract {
 
                     } catch (Exception e) {
 
-                        val deficiencyOrigin = Identifier.classIdentifier(
-                                LogicalType.eager(correspondingClass, objSpec.getSpecId().asString()));
+                        val deficiencyOrigin = Identifier.classIdentifier(objSpec.getLogicalType());
                         val facetHolder = objSpec;
 
                         super.onFailure(
@@ -155,12 +154,11 @@ public class TitlesAndTranslationsValidator extends MetaModelValidatorAbstract {
 
             } catch (Exception e) {
 
-                val facetHolder = specificationLoader.loadSpecification(MessageRegistry.class);
-                val deficiencyOrigin = Identifier.classIdentifier(
-                        LogicalType.eager(MessageRegistry.class, facetHolder.getSpecId().asString()));
+                val spec = specificationLoader.loadSpecification(MessageRegistry.class);
+                val deficiencyOrigin = Identifier.classIdentifier(spec.getLogicalType());
 
                 super.onFailure(
-                        facetHolder, 
+                        spec, 
                         deficiencyOrigin, 
                         "Failed to translate message %s from MessageRegistry", 
                         "" + message);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
index 8c77c75..8a4d366 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
@@ -34,7 +34,6 @@ import java.util.stream.Stream;
 import javax.annotation.Nullable;
 
 import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.repository.EntityState;
 import org.apache.isis.commons.collections.Can;
@@ -115,8 +114,7 @@ public final class ManagedObjects {
     
     public static Optional<String> getDomainType(ManagedObject managedObject) {
         return spec(managedObject)
-                .map(ObjectSpecification::getSpecId)
-                .map(ObjectSpecId::asString);
+                .map(ObjectSpecification::getLogicalTypeName);
     }
     
     // -- IDENTIFICATION
@@ -470,7 +468,7 @@ public final class ManagedObjects {
                         EntityState.PERSISTABLE_ATTACHED, 
                         entityState,
                         ()-> String.format("entity %s is required to be attached (not detached)", 
-                                managedObject.getSpecification().getSpecId()));
+                                managedObject.getSpecification().getLogicalTypeName()));
             }
             return managedObject;
         }
@@ -495,7 +493,7 @@ public final class ManagedObjects {
                     && !managedObject.isRootOidMemoized()) {
                 val msg = String.format("entity %s is required to have a memoized ID, "
                         + "otherwise cannot re-attach", 
-                        managedObject.getSpecification().getSpecId());
+                        managedObject.getSpecification().getLogicalTypeName());
                 log.error(msg); // in case exception gets swallowed
                 throw _Exceptions.illegalState(msg);
             }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
index cf6f9cc..f1ecbf6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
@@ -31,10 +31,8 @@ import java.util.stream.Stream;
 
 import javax.annotation.Nullable;
 
-import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.exceptions.UnrecoverableException;
-import org.apache.isis.applib.id.LogicalType;
-import org.apache.isis.applib.id.ObjectSpecId;
+import org.apache.isis.applib.id.HasLogicalType;
 import org.apache.isis.applib.services.metamodel.BeanSort;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.collections._Streams;
@@ -53,7 +51,6 @@ import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet;
 import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
 import org.apache.isis.core.metamodel.facets.object.icon.IconFacet;
 import org.apache.isis.core.metamodel.facets.object.immutable.ImmutableFacet;
-import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
 import org.apache.isis.core.metamodel.facets.object.parented.ParentedCollectionFacet;
 import org.apache.isis.core.metamodel.facets.object.parseable.ParseableFacet;
 import org.apache.isis.core.metamodel.facets.object.plural.PluralFacet;
@@ -64,12 +61,10 @@ import org.apache.isis.core.metamodel.interactions.ObjectTitleContext;
 import org.apache.isis.core.metamodel.interactions.ObjectValidityContext;
 import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
 import org.apache.isis.core.metamodel.objectmanager.create.ObjectCreator;
-import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutorRegistry;
 import org.apache.isis.core.metamodel.spec.feature.MixedIn;
 import org.apache.isis.core.metamodel.spec.feature.ObjectActionContainer;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationContainer;
 import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
-import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.core.metamodel.specloader.specimpl.IntrospectionState;
 import org.apache.isis.core.metamodel.specloader.specimpl.MixedInMember;
 
@@ -92,7 +87,8 @@ extends
     ObjectActionContainer,
     ObjectAssociationContainer, 
     Hierarchical, 
-    DefaultProvider {
+    DefaultProvider,
+    HasLogicalType {
 
     final class Comparators{
         private Comparators(){}
@@ -105,7 +101,7 @@ extends
                 (final ObjectSpecification s1, final ObjectSpecification s2) -> 
         s1.getShortIdentifier().compareToIgnoreCase(s2.getShortIdentifier());
     }
-
+    
     /**
      * @param memberId
      * @return optionally the ObjectMember associated with given {@code memberId}, 
@@ -147,28 +143,6 @@ extends
     Class<?> getCorrespondingClass();
 
     /**
-     * Returns the (unique) spec Id, as per the {@link ObjectSpecIdFacet}.
-     *
-     * <p>
-     * This will typically be the value of the {@link DomainObject#objectType()} annotation attribute.
-     * If none has been specified then will default to the fully qualified class name (with
-     * {@link ClassSubstitutorRegistry class name substituted} if necessary to allow for runtime bytecode enhancement.
-     *
-     * <p>
-     * The {@link ObjectSpecification} can be retrieved using {@link SpecificationLoader#lookupBySpecIdElseLoad(ObjectSpecId)}}.
-     */
-    @Deprecated
-    default ObjectSpecId getSpecId() {
-        throw _Exceptions.unsupportedOperation();
-    }
-    
-    LogicalType getLogicalType();
-    
-    default String getLogicalTypeName() {
-        return getLogicalType().getLogicalTypeName();
-    }
-
-    /**
      * Returns an (immutable) "full" identifier for this specification.
      *
      * <p>
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
index a0937a0..3b7a625 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
@@ -254,7 +254,7 @@ public interface ObjectAction extends ObjectMember {
             final InteractionInitiatedBy interactionInitiatedBy);
 
     default String getCssClass(String prefix) {
-        final String ownerId = getOnType().getSpecId().asString().replace(".", "-");
+        final String ownerId = getOnType().getLogicalTypeName().replace(".", "-");
         return prefix + ownerId + "-" + getId();
     }
 
@@ -314,7 +314,7 @@ public interface ObjectAction extends ObjectMember {
             @SuppressWarnings("unused")
             final Identifier identifier = action.getIdentifier();
 
-            final String className = action.getOnType().getSpecId().asString().replace(".","-");
+            final String className = action.getOnType().getLogicalTypeName().replace(".","-");
             final String actionId = action.getId();
             return className + "-" + actionId;
         }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/OneToOneAssociation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/OneToOneAssociation.java
index 7eea021..c14b7d9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/OneToOneAssociation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/OneToOneAssociation.java
@@ -62,7 +62,7 @@ public interface OneToOneAssociation extends ObjectAssociation, OneToOneFeature,
 
 
     default String getCssClass(String prefix) {
-        final String ownerSpecId = getOnType().getSpecId().asString().replace(".", "-");
+        final String ownerSpecId = getOnType().getLogicalTypeName().replace(".", "-");
         final String memberId = getIdentifier().getMemberName();
         return prefix + ownerSpecId + "-" + memberId;
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
index 29ee7ef..0ff85e2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
@@ -93,7 +93,7 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
         identifier = Identifier.actionIdentifier(
                 LogicalType.eager(
                         getOnType().getCorrespondingClass(),
-                        getOnType().getSpecId().asString()),
+                        getOnType().getLogicalTypeName()),
                 getId(), 
                 memberParameterClassNames);
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
index 96240ac..5e6cb3c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
@@ -228,11 +228,11 @@ implements ObjectSpecification {
         return FeatureType.OBJECT;
     }
 
-    @Override //TODO[2553] 
-    @Deprecated //use getLogicalTypeName() instead
-    public ObjectSpecId getSpecId() {
-        return specIdLazy.get();
-    }
+//    @Override //TODO[2553] 
+//    @Deprecated //use getLogicalTypeName() instead
+//    public ObjectSpecId getSpecId() {
+//        return specIdLazy.get();
+//    }
     
     @Override
     public LogicalType getLogicalType() {
@@ -479,16 +479,11 @@ implements ObjectSpecification {
     @Override
     public boolean isOfType(final ObjectSpecification other) {
         
-        // do the comparison using value types because of a possible aliasing/race condition
-        // in matchesParameterOf when building up contributed associations
-        if (other.getSpecId().equals(this.getSpecId())) {
-            return true;
-        }
-        
         val thisClass = this.getCorrespondingClass();
         val otherClass = other.getCorrespondingClass();
         
-        return otherClass.isAssignableFrom(thisClass);
+        return thisClass == otherClass 
+                || otherClass.isAssignableFrom(thisClass);
         
 //XXX legacy of ...        
 //        
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
index 167fb51..5e8cfca 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
@@ -131,7 +131,7 @@ public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault imp
         identifier = Identifier.actionIdentifier(
                 LogicalType.eager(
                         mixeeSpec.getCorrespondingClass(), 
-                        mixeeSpec.getSpecId().asString()), 
+                        mixeeSpec.getLogicalTypeName()), 
                 getId(), 
                 memberParameterNames);
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
index c487943..6c591a0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
@@ -111,7 +111,7 @@ public class OneToOneAssociationMixedIn extends OneToOneAssociationDefault imple
         identifier = Identifier.actionIdentifier(
                 LogicalType.eager(
                         mixeeSpec.getCorrespondingClass(), 
-                        mixeeSpec.getSpecId().asString()),
+                        mixeeSpec.getLogicalTypeName()),
                 getId(), 
                 memberParameterClassNames);
     }
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/bookmarks/BookmarkServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/bookmarks/BookmarkServiceDefault.java
index 12c8bc9..46ef605 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/bookmarks/BookmarkServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/bookmarks/BookmarkServiceDefault.java
@@ -113,7 +113,7 @@ public class BookmarkServiceDefault implements BookmarkService, SerializingAdapt
     @Override
     public Bookmark bookmarkFor(Class<?> cls, String identifier) {
         val spec = specificationLoader.loadSpecification(cls);
-        val objectType = spec.getSpecId().asString();
+        val objectType = spec.getLogicalTypeName();
         return Bookmark.of(objectType, identifier);
     }
 
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/menubars/bootstrap3/MenuBarsServiceBS3.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/menubars/bootstrap3/MenuBarsServiceBS3.java
index e1cc551..98392d6 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/menubars/bootstrap3/MenuBarsServiceBS3.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/menubars/bootstrap3/MenuBarsServiceBS3.java
@@ -283,7 +283,7 @@ public class MenuBarsServiceBS3 implements MenuBarsService {
                 }
 
                 ObjectAction objectAction = serviceAndAction.getObjectAction();
-                final String objectType = serviceAndAction.getServiceAdapter().getSpecification().getSpecId().asString();
+                final String objectType = serviceAndAction.getServiceAdapter().getSpecification().getLogicalTypeName();
                 ServiceActionLayoutData action = new ServiceActionLayoutData(objectType, objectAction.getId());
                 action.setNamed(objectAction.getName());
                 menuSection.getServiceActions().add(action);
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java
index 1b62e8c..40ac6e0 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java
@@ -25,7 +25,6 @@ import java.util.stream.Collectors;
 
 import javax.inject.Inject;
 
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@@ -133,8 +132,7 @@ public abstract class AbstractRoleAndPermissionsFixtureScript extends FixtureScr
     
     private String asFeatureFqns(Class<?> cls) {
         return Optional.ofNullable(specificationLoader.loadSpecification(cls))
-                .map(ObjectSpecification::getSpecId)
-                .map(ObjectSpecId::asString)
+                .map(ObjectSpecification::getLogicalTypeName)
                 .orElseGet(()->cls.getName());
     }
 
diff --git a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/rest/DomainObjectResourceTest.java b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/rest/DomainObjectResourceTest.java
index 6df13b4..05a7cfd 100644
--- a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/rest/DomainObjectResourceTest.java
+++ b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/rest/DomainObjectResourceTest.java
@@ -91,7 +91,7 @@ class DomainObjectResourceTest {
         val layoutDemo = factoryService.viewModel(LayoutDemo.class);
         val objectAdapter = objectManager.adapt(layoutDemo);
         val spec = objectAdapter.getSpecification();
-        val domainType = spec.getSpecId().asString();
+        val domainType = spec.getLogicalTypeName();
         val instanceId = objectManager.identifyObject(objectAdapter).getIdentifier(); //TODO also needs URL encoding
 
         val layoutResourceDescriptor = 
@@ -127,7 +127,7 @@ class DomainObjectResourceTest {
         val blobDemo = factoryService.viewModel(BlobDemo.class);
         val objectAdapter = objectManager.adapt(blobDemo);
         val spec = objectAdapter.getSpecification();
-        val domainType = spec.getSpecId().asString();
+        val domainType = spec.getLogicalTypeName();
         val instanceId = objectManager.identifyObject(objectAdapter).getIdentifier(); //TODO also needs URL encoding
 
         val layoutResourceDescriptor = 
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/mementos/ActionMemento.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/mementos/ActionMemento.java
index 61a710b..fe15f69 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/mementos/ActionMemento.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/mementos/ActionMemento.java
@@ -22,35 +22,36 @@ package org.apache.isis.viewer.common.model.mementos;
 import java.io.Serializable;
 import java.util.function.Supplier;
 
-import org.apache.isis.applib.id.ObjectSpecId;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.core.metamodel.spec.ActionType;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 
+import lombok.Getter;
 import lombok.val;
 
 /**
- * {@link Serializable} represention of a {@link ObjectAction}
+ * {@link Serializable} representation of a {@link ObjectAction}
  */
 public class ActionMemento implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    private final ObjectSpecId owningType;
+    @Getter private final LogicalType owningType;
     private final ActionType actionType;
     private final String nameParmsId;
 
     private transient ObjectAction action;
 
     public ActionMemento(final ObjectAction action) {
-        this(action.getOnType().getSpecId(), 
+        this(action.getOnType().getLogicalType(), 
                 action.getType(), 
                 action.getIdentifier().getMemberNameAndParameterClassNamesIdentityString(), 
                 action);
     }
 
     public ActionMemento(
-            final ObjectSpecId owningType,
+            final LogicalType owningType,
             final ActionType actionType,
             final String nameParmsId,
             final SpecificationLoader specificationLoader) {
@@ -58,20 +59,16 @@ public class ActionMemento implements Serializable {
     }
 
     private ActionMemento(
-            final ObjectSpecId owningSpecId,
+            final LogicalType owningType,
             final ActionType actionType,
             final String nameParmsId,
             final ObjectAction action) {
-        this.owningType = owningSpecId;
+        this.owningType = owningType;
         this.actionType = actionType;
         this.nameParmsId = nameParmsId;
         this.action = action;
     }
 
-    public ObjectSpecId getOwningType() {
-        return owningType;
-    }
-
     public ActionType getActionType() {
         return actionType;
     }
@@ -88,12 +85,12 @@ public class ActionMemento implements Serializable {
     }
 
     private static ObjectAction actionFor(
-            ObjectSpecId owningType,
+            LogicalType owningType,
             ActionType actionType,
             String nameParmsId,
             SpecificationLoader specificationLoader) {
         
-        val objectSpec = specificationLoader.lookupBySpecIdElseLoad(owningType.asString());
+        val objectSpec = specificationLoader.lookupBySpecIdElseLoad(owningType);
         return objectSpec.getActionElseFail(nameParmsId, actionType);
     }
 
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModelProvider.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModelProvider.java
index 6287986..330dd2f 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModelProvider.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModelProvider.java
@@ -27,7 +27,6 @@ import javax.inject.Inject;
 import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.DomainServiceLayout;
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facets.object.domainservicelayout.DomainServiceLayoutFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
@@ -50,8 +49,7 @@ public class MenuUiModelProvider {
         return metaModelContext.streamServiceAdapters()
                 .filter(with(menuBarSelect))
                 .map(ManagedObject::getSpecification)
-                .map(ObjectSpecification::getSpecId)
-                .map(ObjectSpecId::asString)
+                .map(ObjectSpecification::getLogicalTypeName)
                 .collect(Collectors.toList());
     }
 
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
index 7014cdd..fe5d2d1 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
@@ -24,7 +24,6 @@ import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import org.apache.isis.applib.annotation.DomainServiceLayout;
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.facets.object.domainservicelayout.DomainServiceLayoutFacet;
 import org.apache.isis.core.metamodel.facets.object.title.TitleFacet;
@@ -412,7 +411,7 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
                 new DomainObjectReprRenderer(getResourceContext(), null, JsonRepresentation.newMap());
         final JsonRepresentation domainObjectRepr = renderer.with(objectAdapter).asPersistLinkArguments().render();
 
-        final String domainType = objectAdapter.getSpecification().getSpecId().asString();
+        final String domainType = objectAdapter.getSpecification().getLogicalTypeName();
         final LinkBuilder persistLinkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.PERSIST.getName(), RepresentationType.DOMAIN_OBJECT, "objects/%s", domainType).withHttpMethod(RestfulHttpMethod.POST).withArguments(domainObjectRepr);
         getLinks().arrayAdd(persistLinkBuilder.build());
     }
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoder.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoder.java
index b174731..20c1d48 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoder.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoder.java
@@ -18,10 +18,8 @@
  */
 package org.apache.isis.viewer.restfulobjects.rendering.domainobjects;
 
-import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
-import java.util.stream.Collectors;
 
 import javax.annotation.Nullable;
 import javax.annotation.PostConstruct;
@@ -38,8 +36,7 @@ import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
-import org.apache.isis.applib.id.ObjectSpecId;
-import org.apache.isis.commons.internal.base._NullSafe;
+import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
@@ -50,6 +47,7 @@ import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 
 import static org.apache.isis.commons.internal.base._With.requires;
 
+import lombok.Getter;
 import lombok.NonNull;
 import lombok.val;
 
@@ -79,12 +77,10 @@ public class JsonValueEncoder {
             .forEach(this::registerConverter);
     }
     
-    private Map<ObjectSpecId, JsonValueConverter> converterBySpecId = _Maps.newLinkedHashMap();
+    private Map<Class<?>, JsonValueConverter> converterByClass = _Maps.newLinkedHashMap();
 
     private void registerConverter(JsonValueConverter jvc) {
-        for (val specId : jvc.getSpecIds()) {
-            converterBySpecId.put(specId, jvc);
-        }
+        jvc.getClasses().forEach(cls->converterByClass.put(cls, jvc));
     }
 
     public ManagedObject asAdapter(
@@ -107,8 +103,8 @@ public class JsonValueEncoder {
             throw new IllegalArgumentException(reason);
         }
 
-        final ObjectSpecId specId = objectSpec.getSpecId();
-        final JsonValueConverter jvc = converterBySpecId.get(specId);
+        val cls = objectSpec.getCorrespondingClass();
+        final JsonValueConverter jvc = converterByClass.get(cls);
         if(jvc == null) {
             // best effort
             if (argValueRepr.isString()) {
@@ -144,8 +140,8 @@ public class JsonValueEncoder {
             String format,
             boolean suppressExtensions) {
 
-        val specId = objectSpecification.getSpecId();
-        val jsonValueConverter = converterBySpecId.get(specId);
+        val cls = objectSpecification.getCorrespondingClass();
+        val jsonValueConverter = converterByClass.get(cls);
         if(jsonValueConverter != null) {
             return jsonValueConverter.appendValueAndFormat(objectAdapter, format, repr, suppressExtensions);
         } else {
@@ -154,7 +150,7 @@ public class JsonValueEncoder {
                 throw _Exceptions.illegalArgument(
                         "objectSpec '%s' expected to have EncodableFacet "
                         + "or a registered JsonValueConverter", 
-                        specId);
+                        objectSpecification.getLogicalTypeName());
             }
             Object value = objectAdapter != null
                     ? encodableFacet.toEncodedString(objectAdapter)
@@ -171,8 +167,9 @@ public class JsonValueEncoder {
         requires(adapter, "adapter");
         
         val objectSpec = adapter.getSpecification();
+        val cls = objectSpec.getCorrespondingClass();
         
-        val jsonValueConverter = converterBySpecId.get(objectSpec.getSpecId());
+        val jsonValueConverter = converterByClass.get(cls);
         if(jsonValueConverter != null) {
             return jsonValueConverter.asObject(adapter, format);
         }
@@ -213,18 +210,13 @@ public class JsonValueEncoder {
 
         protected final String format;
         protected final String xIsisFormat;
-        private final Class<?>[] classes;
+        
+        @Getter private final Can<Class<?>> classes;
 
         public JsonValueConverter(String format, String xIsisFormat, Class<?>... classes) {
             this.format = format;
             this.xIsisFormat = xIsisFormat;
-            this.classes = classes;
-        }
-
-        public List<ObjectSpecId> getSpecIds() {
-            return _NullSafe.stream(classes)
-                    .map((Class<?> cls) ->ObjectSpecId.of(cls.getName()))
-                    .collect(Collectors.toList());
+            this.classes = Can.ofArray(classes);
         }
 
         /**
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeMemberReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeMemberReprRenderer.java
index b9a583a..8c76a7a 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeMemberReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeMemberReprRenderer.java
@@ -70,7 +70,7 @@ public abstract class AbstractTypeMemberReprRenderer<R extends ReprRendererAbstr
         final ObjectMember objectMember = getObjectFeature();
         final LinkBuilder linkBuilder = LinkBuilder.newBuilder(
                 getResourceContext(), Rel.SELF.getName(), getMediaType(),
-                "domain-types/%s/%s%s", getParentSpecification().getSpecId().asString(), getMemberType().getUrlPart(), objectMember.getId());
+                "domain-types/%s/%s%s", getParentSpecification().getLogicalTypeName(), getMemberType().getUrlPart(), objectMember.getId());
         getLinks().arrayAdd(linkBuilder.build());
     }
 
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionDescriptionReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionDescriptionReprRenderer.java
index e3d29b3..8c17c19 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionDescriptionReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionDescriptionReprRenderer.java
@@ -34,7 +34,7 @@ import lombok.val;
 public class ActionDescriptionReprRenderer extends AbstractTypeMemberReprRenderer<ActionDescriptionReprRenderer, ObjectAction> {
 
     public static LinkBuilder newLinkToBuilder(final IResourceContext resourceContext, final Rel rel, final ObjectSpecification objectSpecification, final ObjectAction objectAction) {
-        final String domainType = objectSpecification.getSpecId().asString();
+        final String domainType = objectSpecification.getLogicalTypeName();
         final String actionId = objectAction.getId();
         final String url = "domain-types/" + domainType + "/actions/" + actionId;
         return LinkBuilder.newBuilder(resourceContext, rel.getName(), RepresentationType.ACTION_DESCRIPTION, url);
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionParameterDescriptionReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionParameterDescriptionReprRenderer.java
index 231f65b..a3cae31 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionParameterDescriptionReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionParameterDescriptionReprRenderer.java
@@ -32,7 +32,7 @@ import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 public class ActionParameterDescriptionReprRenderer extends AbstractTypeFeatureReprRenderer<ActionParameterDescriptionReprRenderer, ObjectActionParameter> {
 
     public static LinkBuilder newLinkToBuilder(final IResourceContext resourceContext, final Rel rel, final ObjectSpecification objectSpecification, final ObjectActionParameter objectActionParameter) {
-        final String domainType = objectSpecification.getSpecId().asString();
+        final String domainType = objectSpecification.getLogicalTypeName();
         final ObjectAction objectAction = objectActionParameter.getAction();
         final String actionId = objectAction.getId();
         final String paramName = objectActionParameter.getName();
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/CollectionDescriptionReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/CollectionDescriptionReprRenderer.java
index 7be4545..89355ae 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/CollectionDescriptionReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/CollectionDescriptionReprRenderer.java
@@ -30,7 +30,7 @@ import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 public class CollectionDescriptionReprRenderer extends AbstractTypeMemberReprRenderer<CollectionDescriptionReprRenderer, OneToManyAssociation> {
 
     public static LinkBuilder newLinkToBuilder(final IResourceContext resourceContext, final Rel rel, final ObjectSpecification objectSpecification, final OneToManyAssociation collection) {
-        final String domainType = objectSpecification.getSpecId().asString();
+        final String domainType = objectSpecification.getLogicalTypeName();
         final String collectionId = collection.getId();
         final String url = "domain-types/" + domainType + "/collections/" + collectionId;
         return LinkBuilder.newBuilder(resourceContext, rel.getName(), RepresentationType.COLLECTION_DESCRIPTION, url);
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java
index 901ac61..0515334 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java
@@ -39,7 +39,7 @@ import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 public class DomainTypeReprRenderer extends ReprRendererAbstract<DomainTypeReprRenderer, ObjectSpecification> {
 
     public static LinkBuilder newLinkToBuilder(final IResourceContext resourceContext, final Rel rel, final ObjectSpecification objectSpec) {
-        final String typeFullName = objectSpec.getSpecId().asString();
+        final String typeFullName = objectSpec.getLogicalTypeName();
         final String url = String.format("domain-types/%s", typeFullName);
         return LinkBuilder.newBuilder(resourceContext, rel.getName(), RepresentationType.DOMAIN_TYPE, url);
     }
@@ -48,7 +48,7 @@ public class DomainTypeReprRenderer extends ReprRendererAbstract<DomainTypeReprR
             final IResourceContext resourceContext,
             final ObjectSpecification objectSpec) {
         final Rel rel = Rel.LAYOUT;
-        final String typeFullName = objectSpec.getSpecId().asString();
+        final String typeFullName = objectSpec.getLogicalTypeName();
         final String url = String.format("domain-types/%s/layout", typeFullName);
         return LinkBuilder.newBuilder(resourceContext, rel.getName(), RepresentationType.LAYOUT, url);
     }
@@ -135,7 +135,7 @@ public class DomainTypeReprRenderer extends ReprRendererAbstract<DomainTypeReprR
     }
 
     private JsonRepresentation linkToIsSubtypeOf() {
-        final String url = "domain-types/" + objectSpecification.getSpecId().asString() + "/type-actions/isSubtypeOf/invoke";
+        final String url = "domain-types/" + objectSpecification.getLogicalTypeName() + "/type-actions/isSubtypeOf/invoke";
 
         final LinkBuilder linkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.INVOKE.andParam("typeaction", "isSubtypeOf"), RepresentationType.TYPE_ACTION_RESULT, url);
         final JsonRepresentation arguments = argumentsTo(getResourceContext(), "supertype", null);
@@ -144,7 +144,7 @@ public class DomainTypeReprRenderer extends ReprRendererAbstract<DomainTypeReprR
     }
 
     private JsonRepresentation linkToIsSupertypeOf() {
-        final String url = "domain-types/" + objectSpecification.getSpecId().asString() + "/type-actions/isSupertypeOf/invoke";
+        final String url = "domain-types/" + objectSpecification.getLogicalTypeName() + "/type-actions/isSupertypeOf/invoke";
 
         final LinkBuilder linkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.INVOKE.andParam("typeaction", "isSupertypeOf"), RepresentationType.TYPE_ACTION_RESULT, url);
         final JsonRepresentation arguments = argumentsTo(getResourceContext(), "subtype", null);
@@ -157,7 +157,7 @@ public class DomainTypeReprRenderer extends ReprRendererAbstract<DomainTypeReprR
         final JsonRepresentation link = JsonRepresentation.newMap();
         arguments.mapPut(paramName, link);
         if (objectSpec != null) {
-            link.mapPut("href", resourceContext.urlFor("domain-types/" + objectSpec.getSpecId().asString()));
+            link.mapPut("href", resourceContext.urlFor("domain-types/" + objectSpec.getLogicalTypeName()));
         } else {
             link.mapPut("href", NullNode.instance);
         }
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/PropertyDescriptionReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/PropertyDescriptionReprRenderer.java
index a150369..0cc5a62 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/PropertyDescriptionReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/PropertyDescriptionReprRenderer.java
@@ -31,7 +31,7 @@ import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 public class PropertyDescriptionReprRenderer extends AbstractTypeMemberReprRenderer<PropertyDescriptionReprRenderer, OneToOneAssociation> {
 
     public static LinkBuilder newLinkToBuilder(final IResourceContext resourceContext, final Rel rel, final ObjectSpecification objectSpecification, final OneToOneAssociation property) {
-        final String domainType = objectSpecification.getSpecId().asString();
+        final String domainType = objectSpecification.getLogicalTypeName();
         final String propertyId = property.getId();
         final String url = "domain-types/" + domainType + "/properties/" + propertyId;
         return LinkBuilder.newBuilder(resourceContext, rel.getName(), RepresentationType.PROPERTY_DESCRIPTION, url);
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeListReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeListReprRenderer.java
index 62a522f..2abbd6c 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeListReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeListReprRenderer.java
@@ -53,7 +53,7 @@ extends ReprRendererAbstract<TypeListReprRenderer, Can<ObjectSpecification>> {
 
         final JsonRepresentation specList = JsonRepresentation.newArray();
         for (final ObjectSpecification objectSpec : specifications) {
-            final LinkBuilder linkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.DOMAIN_TYPE.getName(), RepresentationType.DOMAIN_TYPE, "domain-types/%s", objectSpec.getSpecId().asString());
+            final LinkBuilder linkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.DOMAIN_TYPE.getName(), RepresentationType.DOMAIN_TYPE, "domain-types/%s", objectSpec.getLogicalTypeName());
             specList.arrayAdd(linkBuilder.build());
         }
 
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
index 8fd722b..5b3ec9b 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
@@ -239,7 +239,7 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
     }
 
     private static String actionOwningTypeFrom(final ObjectAndActionInvocation objectAndActionInvocation) {
-        return objectAndActionInvocation.getAction().getOnType().getSpecId().asString();
+        return objectAndActionInvocation.getAction().getOnType().getLogicalTypeName();
     }
 
     private static String actionIdFrom(final ObjectAndActionInvocation objectAndActionInvocation) {
@@ -286,7 +286,7 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
         final String title = titleFrom(collectionAdapters, elementSpec);
 
         final DomainObjectList list = new DomainObjectList(
-                title, elementSpec.getSpecId().asString(), actionOwningType, actionId, actionArguments);
+                title, elementSpec.getLogicalTypeName(), actionOwningType, actionId, actionArguments);
         for (val adapter : collectionAdapters) {
             list.getObjects().add(adapter.getPojo());
         }
diff --git a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_appendValueAndFormat.java b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_appendValueAndFormat.java
index e60aab1..8f306d1 100644
--- a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_appendValueAndFormat.java
+++ b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_appendValueAndFormat.java
@@ -30,16 +30,16 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.nullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
 
+import org.apache.isis.applib.id.LogicalType;
+import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
-import org.apache.isis.applib.id.ObjectSpecId;
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 
 public class JsonValueEncoderTest_appendValueAndFormat {
@@ -398,8 +398,11 @@ public class JsonValueEncoderTest_appendValueAndFormat {
     private void allowingObjectSpecToReturnSpecIdFor(final Class<?> cls) {
         context.checking(new Expectations() {
             {
-                oneOf(mockObjectSpec).getSpecId();
-                will(returnValue(ObjectSpecId.of(cls.getName())));
+                allowing(mockObjectSpec).getCorrespondingClass();
+                will(returnValue(cls));
+                
+                allowing(mockObjectSpec).getLogicalType();
+                will(returnValue(LogicalType.fqcn(cls)));
                 
                 allowing(mockObjectSpec).getFacet(EncodableFacet.class);
                 will(returnValue(null));
diff --git a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java
index b976178..b0ace0a 100644
--- a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java
+++ b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java
@@ -37,19 +37,19 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
-import static org.hamcrest.MatcherAssert.assertThat;
 
+import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
+import org.apache.isis.applib.id.LogicalType;
+import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
-import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
-import org.apache.isis.applib.id.ObjectSpecId;
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 
 import lombok.val;
@@ -390,8 +390,8 @@ public class JsonValueEncoderTest_asAdapter {
                 allowing(mockObjectSpec).getCorrespondingClass();
                 will(returnValue(result));
 
-                allowing(mockObjectSpec).getSpecId();
-                will(returnValue(ObjectSpecId.of(result.getName())));
+                allowing(mockObjectSpec).getLogicalType();
+                will(returnValue(LogicalType.fqcn(result)));
 
             }
         });
diff --git a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asObject.java b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asObject.java
index 18cfba1..7ed2904 100644
--- a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asObject.java
+++ b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asObject.java
@@ -31,13 +31,13 @@ import org.junit.Test;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertSame;
 
+import org.apache.isis.applib.id.LogicalType;
+import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
-import org.apache.isis.applib.id.ObjectSpecId;
-import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
 
 public class JsonValueEncoderTest_asObject {
 
@@ -222,8 +222,8 @@ public class JsonValueEncoderTest_asObject {
         });
         context.checking(new Expectations() {
             {
-                allowing(mockObjectSpec).getSpecId();
-                will(returnValue(ObjectSpecId.of(result.getName())));
+                allowing(mockObjectSpec).getLogicalType();
+                will(returnValue(LogicalType.fqcn(result)));
             }
         });
     }
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/CollectionMemento.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/CollectionMemento.java
index 856c27b..8013174 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/CollectionMemento.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/CollectionMemento.java
@@ -21,11 +21,12 @@ package org.apache.isis.viewer.wicket.model.mementos;
 
 import java.io.Serializable;
 
-import org.apache.isis.applib.id.ObjectSpecId;
+import org.apache.isis.applib.id.LogicalType;
 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 lombok.Getter;
 import lombok.val;
 
 /**
@@ -43,7 +44,7 @@ public class CollectionMemento implements Serializable {
         return specificationLoader.lookupBySpecIdElseLoad(logicalType);
     }
 
-    private final ObjectSpecId owningType;
+    @Getter private final LogicalType owningType;
     private final String id;
     private final String collectionId;
     private final String collectionName;
@@ -51,10 +52,10 @@ public class CollectionMemento implements Serializable {
     private transient OneToManyAssociation collection;
 
     public CollectionMemento(final OneToManyAssociation collection) {
-        this(owningSpecFor(collection).getSpecId(), collection.getIdentifier().getMemberName(), collection);
+        this(owningSpecFor(collection).getLogicalType(), collection.getIdentifier().getMemberName(), collection);
     }
 
-    private CollectionMemento(final ObjectSpecId owningType, final String id, final OneToManyAssociation collection) {
+    private CollectionMemento(final LogicalType owningType, final String id, final OneToManyAssociation collection) {
         this.owningType = owningType;
         this.id = id;
         this.collection = collection;
@@ -62,10 +63,6 @@ public class CollectionMemento implements Serializable {
         this.collectionName = collection.getName();
     }
 
-    public ObjectSpecId getOwningType() {
-        return owningType;
-    }
-
     /**
      * Only applies to parented collections, being the id of the collection in
      * the parent (eg <tt>lineItems</tt>).
@@ -100,10 +97,10 @@ public class CollectionMemento implements Serializable {
     }
 
     private static OneToManyAssociation collectionFor(
-            ObjectSpecId owningType,
+            LogicalType owningType,
             String id,
             final SpecificationLoader specificationLoader) {
-        return (OneToManyAssociation) specificationLoader.lookupBySpecIdElseLoad(owningType.asString())
+        return (OneToManyAssociation) specificationLoader.lookupBySpecIdElseLoad(owningType)
                 .getAssociationElseFail(id);
     }
 
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/PageParameterUtil.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/PageParameterUtil.java
index 809cf80..105596a 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/PageParameterUtil.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/PageParameterUtil.java
@@ -25,7 +25,6 @@ import java.util.regex.Pattern;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.primitives._Ints;
 import org.apache.isis.core.metamodel.adapter.oid.Oid;
@@ -140,10 +139,13 @@ public class PageParameterUtil {
             IsisAppCommonContext commonContext,
             PageParameters pageParameters) {
 
-        final ObjectSpecId owningSpec = ObjectSpecId.of(PageParameterNames.ACTION_OWNING_SPEC.getStringFrom(pageParameters));
+        val specLoader = commonContext.getSpecificationLoader();
+        val owningLogicalTypeName = PageParameterNames.ACTION_OWNING_SPEC.getStringFrom(pageParameters);
+        val owningLogicalType = specLoader.lookupLogicalType(owningLogicalTypeName);
+        
         final ActionType actionType = PageParameterNames.ACTION_TYPE.getEnumFrom(pageParameters, ActionType.class);
         final String actionNameParms = PageParameterNames.ACTION_ID.getStringFrom(pageParameters);
-        return new ActionMemento(owningSpec, actionType, actionNameParms, commonContext.getSpecificationLoader());
+        return new ActionMemento(owningLogicalType, actionType, actionNameParms, specLoader);
     }
     
     private static final Pattern KEY_VALUE_PATTERN = Pattern.compile("([^=]+)=(.+)");
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
index 2df3121..dab7c1e 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
@@ -52,7 +52,7 @@ public class ActionParametersFormPanel extends PromptFormPanelAbstract<ActionMod
                 new ActionParametersForm("inputForm", this, this.getWicketViewerSettings(), model);
 
         final ObjectAction action = model.getMetaModel();
-        CssClassAppender.appendCssClassTo(inputForm, "isis-" + CssClassAppender.asCssStyle(action.getOnType().getSpecId().asString().replace(".","-") + "-" + action.getId()));
+        CssClassAppender.appendCssClassTo(inputForm, "isis-" + CssClassAppender.asCssStyle(action.getOnType().getLogicalTypeName().replace(".","-") + "-" + action.getId()));
         add(inputForm);
     }
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java
index 38a6d00..8c0ecda 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java
@@ -277,7 +277,7 @@ implements CollectionCountProvider {
         final NamedFacet facet = property.getFacet(NamedFacet.class);
         final boolean escaped = facet == null || facet.escaped();
 
-        final String parentTypeName = property.getOnType().getSpecId().asString();
+        final String parentTypeName = property.getOnType().getLogicalTypeName();
         final String describedAs = mapIfPresentElse(property.getFacet(DescribedAsFacet.class), 
                 DescribedAsFacet::value, null);
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/standalonecollection/StandaloneCollectionPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/standalonecollection/StandaloneCollectionPanel.java
index 7bdda54..a8fa564 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/standalonecollection/StandaloneCollectionPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/standalonecollection/StandaloneCollectionPanel.java
@@ -67,9 +67,9 @@ implements CollectionCountProvider, CollectionSelectorProvider {
         outerDiv.addOrReplace(new Label(StandaloneCollectionPanel.ID_ACTION_NAME, Model.of(action.getName())));
 
         CssClassAppender.appendCssClassTo(outerDiv,
-                CssClassAppender.asCssStyle("isis-" + action.getOnType().getSpecId().asString().replace('.', '-') + "-" + action.getId()));
+                CssClassAppender.asCssStyle("isis-" + action.getOnType().getLogicalTypeName().replace('.', '-') + "-" + action.getId()));
         CssClassAppender.appendCssClassTo(outerDiv,
-                CssClassAppender.asCssStyle("isis-" + entityCollectionModel.getTypeOfSpecification().getSpecId().asString().replace('.','-')));
+                CssClassAppender.asCssStyle("isis-" + entityCollectionModel.getTypeOfSpecification().getLogicalTypeName().replace('.','-')));
 
         // selector
         final CollectionSelectorHelper selectorHelper = new CollectionSelectorHelper(entityCollectionModel, getComponentFactoryRegistry());
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/LinkAndLabelFactoryAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/LinkAndLabelFactoryAbstract.java
index 96ff2708..a8333cc 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/LinkAndLabelFactoryAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/LinkAndLabelFactoryAbstract.java
@@ -241,7 +241,7 @@ implements Serializable {
                     // intercept redirect request to sign-in page
                     Optional.ofNullable(actionModel.getObject())
                     .ifPresent(actionResultAdapter->{
-                        val actionResultSpecId = actionResultAdapter.getSpecification().getSpecId().asString();
+                        val actionResultSpecId = actionResultAdapter.getSpecification().getLogicalTypeName();
                         if(LoginRedirect.OBJECT_TYPE.equals(actionResultSpecId)) {
                             val commonContext = targetEntityModel.getCommonContext();
                             val pageClassRegistry = commonContext.lookupServiceElseFail(PageClassRegistry.class);
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java
index c8a9403..5e23419 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java
@@ -191,7 +191,7 @@ public class EntityPage extends PageAbstract {
 
         WebMarkupContainer entityPageContainer = new WebMarkupContainer("entityPageContainer");
         CssClassAppender.appendCssClassTo(entityPageContainer,
-                CssClassAppender.asCssStyle("isis-" + objectSpec.getSpecId().asString().replace(".","-")));
+                CssClassAppender.asCssStyle("isis-" + objectSpec.getLogicalTypeName().replace(".","-")));
 
         CssClassFacet cssClassFacet = objectSpec.getFacet(CssClassFacet.class);
         if(cssClassFacet != null) {


[isis] 01/11: ISIS-2553: place initial deprecation markers

Posted by ah...@apache.org.
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

commit a1138893b7b383c7e8fadc0d55aed114e2702b7c
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Mar 1 11:23:53 2021 +0100

    ISIS-2553: place initial deprecation markers
---
 api/applib/src/main/java/org/apache/isis/applib/Identifier.java        | 3 +++
 .../isis/core/metamodel/services/appfeat/ApplicationFeatureId.java     | 3 +++
 .../main/java/org/apache/isis/core/metamodel/spec/ObjectSpecId.java    | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/Identifier.java b/api/applib/src/main/java/org/apache/isis/applib/Identifier.java
index 87fd701..12e84ea 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/Identifier.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/Identifier.java
@@ -32,6 +32,9 @@ import lombok.NonNull;
 import lombok.val;
 
 /**
+ * //TODO[2553] needs to be made Serializable, so can act as replacement for ApplicationFeatureId 
+ * 
+ * 
  * Combines {@link TypeIdentifier} and member identification (from properties, collections or actions),
  * to a fully qualified <i>feature</i> identifier.
  * <p> 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
index 1993ced..7ebd562 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
@@ -33,6 +33,7 @@ import static java.util.Comparator.nullsFirst;
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Value;
+import org.apache.isis.applib.id.TypeIdentifier;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.applib.util.Equality;
 import org.apache.isis.applib.util.Hashing;
@@ -52,6 +53,8 @@ import lombok.val;
  * This value is {@link Comparable}, the implementation of which considers 
  * {@link #getType() (feature) type}, {@link #getNamespace() logical package name}, 
  * {@link #getTypeSimpleName() class name} and {@link #getMemberName() member name}.
+ * 
+ * @deprecated use {@link Identifier} instead  
  */
 @Value
 public class ApplicationFeatureId 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecId.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecId.java
index 3057234..d64ffce 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecId.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecId.java
@@ -20,6 +20,7 @@ package org.apache.isis.core.metamodel.spec;
 
 import java.io.Serializable;
 
+import org.apache.isis.applib.id.TypeIdentifier;
 import org.apache.isis.commons.internal.base._Refs;
 import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
 
@@ -36,6 +37,7 @@ import lombok.Value;
  *
  * <p>
  * Has value semantics.
+ * @deprecated use {@link TypeIdentifier} instead
  */
 @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
 @Value


[isis] 10/11: ISIS-2553: improve some java-doc

Posted by ah...@apache.org.
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

commit a2aae4a8cd993a3d00f29b5e7a2642469f799570
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Mar 2 07:32:42 2021 +0100

    ISIS-2553: improve some java-doc
---
 api/applib/src/main/java/org/apache/isis/applib/id/LogicalType.java | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/id/LogicalType.java b/api/applib/src/main/java/org/apache/isis/applib/id/LogicalType.java
index 7b73426..d8d9bde 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/id/LogicalType.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/id/LogicalType.java
@@ -41,8 +41,10 @@ import lombok.val;
  * <p>
  * Equality is driven by the corresponding class exclusively, meaning the logical name is ignored 
  * in order to not cause any side-effects on logical name memoization eg. it happening too early.
- * Meta-model validators will take care, that there is no logical name ambiguity, that is, 
- * there can no LogicalTypes sharing the same corresponding class but having different logical names. 
+ * <p>
+ * Meta-model validators will take care, that there is no logical name ambiguity: 
+ * There cannot be any LogicalTypes sharing the same corresponding class while having different 
+ * logical names. 
  * 
  * @apiNote thread-safe and serializable
  * @since 2.0 {@index}


[isis] 02/11: ISIS-2553: TypeIdentifier: add namespace related getters

Posted by ah...@apache.org.
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

commit fff9628bc5819100031ae0e9b69d67c713b34237
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Mar 1 12:00:52 2021 +0100

    ISIS-2553: TypeIdentifier: add namespace related getters
---
 .../java/org/apache/isis/applib/Identifier.java    | 11 +++++---
 .../org/apache/isis/applib/id/TypeIdentifier.java  | 30 +++++++++++++++++++++-
 2 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/Identifier.java b/api/applib/src/main/java/org/apache/isis/applib/Identifier.java
index 12e84ea..7253d89 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/Identifier.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/Identifier.java
@@ -19,6 +19,7 @@
 
 package org.apache.isis.applib;
 
+import java.io.Serializable;
 import java.util.Objects;
 import java.util.stream.Collectors;
 
@@ -32,9 +33,6 @@ import lombok.NonNull;
 import lombok.val;
 
 /**
- * //TODO[2553] needs to be made Serializable, so can act as replacement for ApplicationFeatureId 
- * 
- * 
  * Combines {@link TypeIdentifier} and member identification (from properties, collections or actions),
  * to a fully qualified <i>feature</i> identifier.
  * <p> 
@@ -44,7 +42,12 @@ import lombok.val;
  * @since 1.x revised for 2.0 {@index}
  * @see TypeIdentifier
  */
-public class Identifier implements Comparable<Identifier> {
+public class Identifier 
+implements 
+    Comparable<Identifier>,
+    Serializable {
+
+    private static final long serialVersionUID = 1L;
 
     /**
      * What type of feature this identifies.
diff --git a/api/applib/src/main/java/org/apache/isis/applib/id/TypeIdentifier.java b/api/applib/src/main/java/org/apache/isis/applib/id/TypeIdentifier.java
index b24bab1..a925402 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/id/TypeIdentifier.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/id/TypeIdentifier.java
@@ -57,7 +57,7 @@ implements
     @ToString.Exclude
     private final Supplier<String> logicalNameProvider;
     
-    @ToString.Exclude // lazy, so don't use in toString
+    @ToString.Exclude // lazy, so don't use in toString (keep free from side-effects)
     private String logicalName;
 
     // -- FACTORIES
@@ -130,6 +130,34 @@ implements
     
     /**
      * The logical type name consists of 2 parts, the <i>namespace</i> and the <i>logical simple name</i>.
+     * <p>
+     * Returns the <i>logical simple name</i> part.
+     * @implNote the result is not memoized, to keep it simple 
+     */
+    public String getLogicalTypeSimpleName() {
+        val logicalTypeName = getLogicalTypeName();
+        final int lastDot = logicalTypeName.lastIndexOf('.');
+        return lastDot >= 0
+            ? logicalTypeName.substring(lastDot + 1)
+            : logicalTypeName;
+    }
+    
+    /**
+     * The logical type name consists of 2 parts, the <i>namespace</i> and the <i>logical simple name</i>.
+     * <p>
+     * Returns the <i>namespace</i> part.
+     * @implNote the result is not memoized, to keep it simple
+     */
+    public String getNamespace() {
+        val logicalTypeName = getLogicalTypeName();
+        final int lastDot = logicalTypeName.lastIndexOf('.');
+        return lastDot >= 0
+            ? logicalTypeName.substring(0, lastDot)
+            : "";
+    }
+    
+    /**
+     * The logical type name consists of 2 parts, the <i>namespace</i> and the <i>logical simple name</i>.
      * Returns a concatenation of <i>namespace</i>, {@code delimiter} and the <i>logical simple name</i>, 
      * whereas in the absence of a <i>namespace</i> returns a concatenation of {@code root} and the 
      * <i>logical simple name</i>.


[isis] 09/11: ISIS-2553: remove ObjectSpecId

Posted by ah...@apache.org.
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

commit ea93a645289e2da13a251738c6bd58c0fd42c037
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Mar 2 07:22:11 2021 +0100

    ISIS-2553: remove ObjectSpecId
---
 .../org/apache/isis/applib/id/HasLogicalType.java  | 14 +----
 .../org/apache/isis/applib/id/LogicalType.java     | 26 +++++++++
 .../org/apache/isis/applib/id/ObjectSpecId.java    | 65 ----------------------
 .../services/appfeat/ApplicationFeatureId.java     |  1 -
 .../metamodel/MetaModelServiceDefault.java         |  1 -
 .../resources/DomainObjectResourceServerside.java  |  1 -
 .../bookmarkedpages/BookmarkedPagesPanel.java      |  1 -
 7 files changed, 27 insertions(+), 82 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java b/api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java
index 60bd6f8..3b33a31 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java
@@ -18,8 +18,6 @@
  */
 package org.apache.isis.applib.id;
 
-import org.apache.isis.applib.annotation.DomainObject;
-
 /**
  * @since 2.0 {@index}
  */
@@ -28,17 +26,7 @@ public interface HasLogicalType {
     LogicalType getLogicalType();
 
     /**
-     * Returns the (unique) logical-type-name, as per the {@link ObjectSpecIdFacet}.
-     *
-     * <p>
-     * This will typically be the value of the {@link DomainObject#objectType()} annotation attribute.
-     * If none has been specified then will default to the fully qualified class name (with
-     * {@link ClassSubstitutorRegistry class name substituted} if necessary to allow for runtime 
-     * bytecode enhancement.
-     *
-     * <p> 
-     * The {@link ObjectSpecification} can be retrieved using 
-     * {@link SpecificationLoader#lookupBySpecIdElseLoad(String)}} passing the logical-type-name as argument.
+     * @see LogicalType#getLogicalTypeName()
      */
     default String getLogicalTypeName() {
         return getLogicalType().getLogicalTypeName();
diff --git a/api/applib/src/main/java/org/apache/isis/applib/id/LogicalType.java b/api/applib/src/main/java/org/apache/isis/applib/id/LogicalType.java
index 360f1e8..7b73426 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/id/LogicalType.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/id/LogicalType.java
@@ -26,6 +26,7 @@ import java.util.function.Supplier;
 
 import javax.annotation.Nullable;
 
+import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 
@@ -37,6 +38,12 @@ import lombok.val;
 
 /**
  * A generalization of Java's class type to also hold a logical name, which can be supplied lazily.
+ * <p>
+ * Equality is driven by the corresponding class exclusively, meaning the logical name is ignored 
+ * in order to not cause any side-effects on logical name memoization eg. it happening too early.
+ * Meta-model validators will take care, that there is no logical name ambiguity, that is, 
+ * there can no LogicalTypes sharing the same corresponding class but having different logical names. 
+ * 
  * @apiNote thread-safe and serializable
  * @since 2.0 {@index}
  */
@@ -120,6 +127,25 @@ implements
         return getCorrespondingClass().getCanonicalName();
     }
     
+    /**
+     * Returns the (unique) logical-type-name, as per the 
+     * {@link ObjectSpecIdFacet}.
+     *
+     * <p>
+     * This will typically be the value of the {@link DomainObject#objectType()} annotation attribute.
+     * If none has been specified then will default to the fully qualified class name (with
+     * {@link ClassSubstitutorRegistry class name substituted} if necessary to allow for runtime 
+     * bytecode enhancement.
+     *
+     * <p> 
+     * The {@link ObjectSpecification} can be retrieved using 
+     * {@link SpecificationLoader#lookupBySpecIdElseLoad(String)}} passing the logical-type-name as argument.
+     * 
+     * @see ClassSubstitutorRegistry
+     * @see ObjectSpecIdFacet
+     * @see ObjectSpecification
+     * @see SpecificationLoader
+     */
     @Synchronized
     public String getLogicalTypeName() {
         if(logicalName == null) {
diff --git a/api/applib/src/main/java/org/apache/isis/applib/id/ObjectSpecId.java b/api/applib/src/main/java/org/apache/isis/applib/id/ObjectSpecId.java
deleted file mode 100644
index ba9d81b..0000000
--- a/api/applib/src/main/java/org/apache/isis/applib/id/ObjectSpecId.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.applib.id;
-
-import java.io.Serializable;
-
-import org.apache.isis.commons.internal.base._Refs;
-
-import static org.apache.isis.commons.internal.base._With.requiresNotEmpty;
-
-import lombok.AccessLevel;
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-import lombok.Value;
-
-/**
- * Represents an {@link org.apache.isis.core.metamodel.spec.ObjectSpecification}, as determined by
- * an {@link org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet}.
- *
- * <p>
- * Has value semantics.
- * @deprecated use {@link LogicalType} instead
- */
-@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
-@Value
-public final class ObjectSpecId implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    @NonNull private final String specId;
-    @NonNull private final String namespace;
-
-    public static ObjectSpecId of(final @NonNull String specId) {
-        requiresNotEmpty(specId, "specId");
-        return new ObjectSpecId(
-                specId, 
-                _Refs.stringRef(specId).cutAtLastIndexOf("."));
-    }
-
-    public String asString() {
-        return specId;
-    }
-
-    @Override
-    public String toString() {
-        return asString();
-    }
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
index ac3ed55..5197607 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
@@ -33,7 +33,6 @@ import static java.util.Comparator.nullsFirst;
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Value;
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.applib.util.Equality;
 import org.apache.isis.applib.util.Hashing;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
index 72c25f6..0648106 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
@@ -30,7 +30,6 @@ import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.commanddto.processor.CommandDtoProcessor;
 import org.apache.isis.applib.services.grid.GridService;
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
index 8474e2c..be54907 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
@@ -39,7 +39,6 @@ import javax.ws.rs.core.Response;
 import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.applib.layout.component.ActionLayoutData;
 import org.apache.isis.applib.layout.component.CollectionLayoutData;
 import org.apache.isis.applib.layout.component.DomainObjectLayoutData;
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.java
index 6379bc5..ca9d985 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.java
@@ -43,7 +43,6 @@ import org.apache.wicket.request.resource.ResourceReference;
 import org.apache.wicket.util.string.Strings;
 
 import org.apache.isis.applib.exceptions.unrecoverable.ObjectNotFoundException;
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.viewer.wicket.model.models.BookmarkTreeNode;


[isis] 08/11: ISIS-2553: using LogicalType instead of ObjectSpecId (5th iteration)

Posted by ah...@apache.org.
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

commit 3f1c8995bfd714a6a6d80d17e545e2c88afdcccb
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Mar 2 07:10:26 2021 +0100

    ISIS-2553: using LogicalType instead of ObjectSpecId (5th iteration)
---
 ...ypeIdentifierTest.java => LogicalTypeTest.java} | 21 +++++++---
 .../applib/id/LogicalTypeTest_valueSemantics.java  | 22 +++++++----
 .../services/appfeat/ApplicationFeatureId.java     |  4 +-
 .../metamodel/MetaModelServiceDefault.java         |  7 ++--
 .../spec/ObjectSpecIdTest_constructor.java         | 45 ----------------------
 5 files changed, 35 insertions(+), 64 deletions(-)

diff --git a/api/applib/src/test/java/org/apache/isis/applib/id/TypeIdentifierTest.java b/api/applib/src/test/java/org/apache/isis/applib/id/LogicalTypeTest.java
similarity index 72%
rename from api/applib/src/test/java/org/apache/isis/applib/id/TypeIdentifierTest.java
rename to api/applib/src/test/java/org/apache/isis/applib/id/LogicalTypeTest.java
index 6698d61..9ee23fc 100644
--- a/api/applib/src/test/java/org/apache/isis/applib/id/TypeIdentifierTest.java
+++ b/api/applib/src/test/java/org/apache/isis/applib/id/LogicalTypeTest.java
@@ -18,21 +18,17 @@
  */
 package org.apache.isis.applib.id;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 import org.apache.isis.applib.SomeDomainClass;
 import org.apache.isis.commons.internal.testing._SerializationTester;
 
 import lombok.val;
 
-class TypeIdentifierTest {
-
-    @BeforeEach
-    void setUp() throws Exception {
-    }
+class LogicalTypeTest {
 
     @Test
     void eager() {
@@ -65,6 +61,19 @@ class TypeIdentifierTest {
                 _SerializationTester.roundtrip(original).getLogicalTypeName(), 
                 original.getLogicalTypeName());
     }
+    
+    @Test
+    void cannotBeEmpty() throws Exception {
+        assertThrows(IllegalArgumentException.class, ()->LogicalType.eager(Object.class, ""));
+        assertThrows(IllegalArgumentException.class, ()->LogicalType.lazy(Object.class, ()->"").getLogicalTypeName());
+    }
 
+    @Test
+    void cannotBeNull()  {
+        assertThrows(NullPointerException.class, ()->LogicalType.lazy(null, ()->"x"));
+        assertThrows(NullPointerException.class, ()->LogicalType.lazy(Object.class, null));
+        assertThrows(NullPointerException.class, ()->LogicalType.eager(null, "x"));
+        assertThrows(IllegalArgumentException.class, ()->LogicalType.eager(Object.class, null));
+    }
 
 }
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_valueSemantics.java b/api/applib/src/test/java/org/apache/isis/applib/id/LogicalTypeTest_valueSemantics.java
similarity index 58%
rename from core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_valueSemantics.java
rename to api/applib/src/test/java/org/apache/isis/applib/id/LogicalTypeTest_valueSemantics.java
index b3808d7..0045823 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_valueSemantics.java
+++ b/api/applib/src/test/java/org/apache/isis/applib/id/LogicalTypeTest_valueSemantics.java
@@ -16,24 +16,30 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.metamodel.spec;
+package org.apache.isis.applib.id;
 
-import java.util.Arrays;
 import java.util.List;
 
-import org.apache.isis.applib.id.ObjectSpecId;
+import org.apache.isis.applib.SomeDomainClass;
+import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.internaltestsupport.contract.ValueTypeContractTestAbstract;
 
-public class ObjectSpecIdTest_valueSemantics extends ValueTypeContractTestAbstract<ObjectSpecId> {
+public class LogicalTypeTest_valueSemantics 
+extends ValueTypeContractTestAbstract<LogicalType> {
 
     @Override
-    protected List<ObjectSpecId> getObjectsWithSameValue() {
-        return Arrays.asList(ObjectSpecId.of("CUS"), ObjectSpecId.of("CUS"), ObjectSpecId.of("CUS"));
+    protected List<LogicalType> getObjectsWithSameValue() {
+        return _Lists.of(
+                LogicalType.fqcn(SomeDomainClass.class),
+                LogicalType.lazy(SomeDomainClass.class, ()->SomeDomainClass.class.getName()));
     }
 
     @Override
-    protected List<ObjectSpecId> getObjectsWithDifferentValue() {
-        return Arrays.asList(ObjectSpecId.of("bUS"), ObjectSpecId.of("CUt"));
+    protected List<LogicalType> getObjectsWithDifferentValue() {
+        return _Lists.of(
+                LogicalType.fqcn(Object.class),
+                LogicalType.lazy(List.class, ()->List.class.getName()));
     }
 
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
index ba3ce09..ac3ed55 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
@@ -214,7 +214,7 @@ implements
     // -- objectSpecId (property)
 
     @Programmatic
-    public ObjectSpecId getObjectSpecId() {
+    public String getLogicalTypeName() {
         if (getTypeSimpleName() == null) {
             return null;
         }
@@ -225,7 +225,7 @@ implements
         }
         buf.append(getTypeSimpleName());
 
-        return ObjectSpecId.of(buf.toString());
+        return buf.toString();
     }
 
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
index 918ffd8..72c25f6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
@@ -39,6 +39,7 @@ import org.apache.isis.applib.services.metamodel.Config;
 import org.apache.isis.applib.services.metamodel.DomainMember;
 import org.apache.isis.applib.services.metamodel.DomainModel;
 import org.apache.isis.applib.services.metamodel.MetaModelService;
+import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.facets.members.publish.command.CommandPublishingFacet;
 import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
@@ -216,12 +217,12 @@ public class MetaModelServiceDefault implements MetaModelService {
         final ApplicationFeatureId featureId = ApplicationFeatureId
                 .newFeature(ApplicationFeatureType.MEMBER, memberIdentifier);
 
-        final ObjectSpecId objectSpecId = featureId.getObjectSpecId();
-        if(objectSpecId == null) {
+        final String logicalTypeName = featureId.getLogicalTypeName();
+        if(_Strings.isNullOrEmpty(logicalTypeName)) {
             return null;
         }
 
-        final ObjectSpecification spec = specificationLoader.lookupBySpecIdElseLoad(objectSpecId.asString());
+        final ObjectSpecification spec = specificationLoader.lookupBySpecIdElseLoad(logicalTypeName);
         if(spec == null) {
             return null;
         }
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_constructor.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_constructor.java
deleted file mode 100644
index 402f616..0000000
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_constructor.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.spec;
-
-import org.junit.Test;
-
-import org.apache.isis.applib.id.ObjectSpecId;
-
-public class ObjectSpecIdTest_constructor {
-
-    @Test
-    public void happyCase() throws Exception {
-        @SuppressWarnings("unused")
-        final ObjectSpecId objectSpecId = ObjectSpecId.of("CUS");
-    }
-
-    @Test(expected=IllegalArgumentException.class)
-    public void cannotBeEmpty() throws Exception {
-        ObjectSpecId.of("");
-    }
-
-
-    @Test(expected=NullPointerException.class)
-    public void cannotBeNull() throws Exception {
-        ObjectSpecId.of(null);
-    }
-
-
-}


[isis] 05/11: ISIS-2553: using LogicalType instead of ObjectSpecId (3rd iteration)

Posted by ah...@apache.org.
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

commit af65382c34efd4e13453301bc8fe6bdef31cfd4b
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Mar 1 19:35:05 2021 +0100

    ISIS-2553: using LogicalType instead of ObjectSpecId (3rd iteration)
---
 .../java/org/apache/isis/applib/id/HasLogicalType.java |  3 +--
 .../specimpl/ObjectSpecificationAbstract.java          | 18 +++++-------------
 .../isis/viewer/wicket/model/links/LinkAndLabel.java   |  2 +-
 .../viewer/wicket/model/models/ManagedObjectModel.java | 18 ++++++++++--------
 .../isis/viewer/wicket/model/models/ScalarModel.java   |  2 +-
 5 files changed, 18 insertions(+), 25 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java b/api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java
index d840a16..60bd6f8 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java
@@ -37,9 +37,8 @@ public interface HasLogicalType {
      * bytecode enhancement.
      *
      * <p> 
-     * TODO[2553] ... no longer true
      * The {@link ObjectSpecification} can be retrieved using 
-     * {@link SpecificationLoader#lookupBySpecIdElseLoad(String)}}.
+     * {@link SpecificationLoader#lookupBySpecIdElseLoad(String)}} passing the logical-type-name as argument.
      */
     default String getLogicalTypeName() {
         return getLogicalType().getLogicalTypeName();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
index 5e6cb3c..17bc46a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
@@ -34,7 +34,6 @@ import javax.enterprise.inject.Vetoed;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.id.LogicalType;
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.applib.services.metamodel.BeanSort;
 import org.apache.isis.commons.collections.ImmutableEnumSet;
 import org.apache.isis.commons.internal.base._Lazy;
@@ -186,7 +185,7 @@ implements ObjectSpecification {
     private final boolean isAbstract;
 
     // derived lazily, cached since immutable
-    private _Lazy<ObjectSpecId> specIdLazy = _Lazy.threadSafe(this::lookupSpecId);
+    private _Lazy<LogicalType> logicalTypeLazy = _Lazy.threadSafe(this::lookupLogicalType);
 
     private ObjectSpecification superclassSpec;
 
@@ -216,7 +215,7 @@ implements ObjectSpecification {
         this.identifier = Identifier.classIdentifier(
                 LogicalType.lazy(
                         introspectedClass,
-                        ()->specIdLazy.get().asString()));
+                        ()->logicalTypeLazy.get().getLogicalTypeName()));
 
         this.facetProcessor = facetProcessor;
         this.postProcessor = postProcessor;
@@ -228,24 +227,17 @@ implements ObjectSpecification {
         return FeatureType.OBJECT;
     }
 
-//    @Override //TODO[2553] 
-//    @Deprecated //use getLogicalTypeName() instead
-//    public ObjectSpecId getSpecId() {
-//        return specIdLazy.get();
-//    }
-    
     @Override
     public LogicalType getLogicalType() {
-        //TODO[2553] add memoization
-        return LogicalType.eager(correspondingClass, specIdLazy.get().asString());
+        return logicalTypeLazy.get();
     }
         
-    private ObjectSpecId lookupSpecId() {
+    private LogicalType lookupLogicalType() {
         val objectSpecIdFacet = getFacet(ObjectSpecIdFacet.class);
         if(objectSpecIdFacet == null) {
             throw new IllegalStateException("could not find an ObjectSpecIdFacet for " + this.getFullIdentifier());
         }
-        return objectSpecIdFacet.value();
+        return LogicalType.eager(correspondingClass, objectSpecIdFacet.value().asString());
     }
 
     /**
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java
index 0fd6e96..dd1acb4 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java
@@ -89,7 +89,7 @@ public final class LinkAndLabel extends LinkAndLabelAbstract {
             this.named = target.getNamed();
             this.actionHolder = (EntityModel) target.getActionHolder();
             // make sure we do this without side-effects
-            this.actionHolderLogicalType = actionHolder.getTypeOfSpecificationId()
+            this.actionHolderLogicalType = actionHolder.getLogicalElementType()
                     .orElseThrow(_Exceptions::unexpectedCodeReach); 
             this.objectActionId = target.getObjectAction().getId();
         }
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ManagedObjectModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ManagedObjectModel.java
index 41b3c53..0ead34e 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ManagedObjectModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ManagedObjectModel.java
@@ -25,7 +25,6 @@ import javax.annotation.Nullable;
 
 import org.apache.isis.applib.annotation.BookmarkPolicy;
 import org.apache.isis.applib.id.LogicalType;
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.collections._Collections;
@@ -38,6 +37,7 @@ import org.apache.isis.core.runtime.context.IsisAppCommonContext;
 import org.apache.isis.core.runtime.memento.ObjectMemento;
 
 import lombok.NonNull;
+import lombok.Synchronized;
 import lombok.val;
 
 /**
@@ -104,7 +104,7 @@ extends ModelAbstract<ManagedObject> {
         
         val pojos = adapter.getPojo();
         memento = super.getMementoService()
-                .mementoForPojos(_Casts.uncheckedCast(pojos), getTypeOfSpecificationId()
+                .mementoForPojos(_Casts.uncheckedCast(pojos), getLogicalElementType()
                         .orElseGet(()->adapter.getElementSpecification().get().getLogicalType()));
     }
     
@@ -129,23 +129,25 @@ extends ModelAbstract<ManagedObject> {
     /**
      * free of side-effects, used for serialization
      * @implNote overriding this must be consistent with {@link #getTypeOfSpecification()}
-     * TODO[2553] rename to getLogicalElementType
      */
-    public Optional<LogicalType> getTypeOfSpecificationId() {
+    public Optional<LogicalType> getLogicalElementType() {
         return Optional.ofNullable(memento)
                 .map(ObjectMemento::getLogicalType);
     }
     
     private transient ObjectSpecification objectSpec;
+    private transient boolean isObjectSpecMemoized = false;
     /**
      * @implNote can be overridden by sub-models (eg {@link ScalarModel}) that know the type of
      * the adapter without there being one. Overriding this must be consistent 
-     * with {@link #getTypeOfSpecificationId()} 
+     * with {@link #getLogicalElementType()} 
      */
+    @Synchronized
     public ObjectSpecification getTypeOfSpecification() {
-        if(objectSpec==null) {
-            val specId = getTypeOfSpecificationId().orElse(null);
-            objectSpec = super.getSpecificationLoader().lookupBySpecIdElseLoad(specId); 
+        if(!isObjectSpecMemoized) {
+            val specId = getLogicalElementType().orElse(null);
+            objectSpec = super.getSpecificationLoader().lookupBySpecIdElseLoad(specId);
+            isObjectSpecMemoized = true;
         }
         return objectSpec;
     }
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
index dde6c25..9a881e6 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
@@ -160,7 +160,7 @@ implements HasRenderingHints, ScalarUiModel, LinksProvider, FormExecutorContext
     }
 
     @Override
-    public Optional<LogicalType> getTypeOfSpecificationId() {
+    public Optional<LogicalType> getLogicalElementType() {
         return Optional.ofNullable(getScalarTypeSpec())
                 .map(ObjectSpecification::getLogicalType);
     }


[isis] 06/11: ISIS-2553: using LogicalType instead of ObjectSpecId (4th iteration)

Posted by ah...@apache.org.
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

commit a088d393df9aa0d5f25a854a26c2d29fba9997df
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Mar 1 19:49:53 2021 +0100

    ISIS-2553: using LogicalType instead of ObjectSpecId (4th iteration)
---
 .../object/objectspecid/ObjectSpecIdFacet.java     |  3 +--
 .../objectspecid/ObjectSpecIdFacetAbstract.java    | 22 ++++++++--------------
 .../ObjectSpecIdFacetOnStandaloneList.java         |  3 +--
 .../metamodel/MetaModelServiceDefault.java         |  7 ++++---
 .../specimpl/ObjectSpecificationAbstract.java      |  2 +-
 .../testspec/ObjectSpecificationStub.java          |  2 +-
 .../service/swagger/internal/Generation.java       |  2 +-
 7 files changed, 17 insertions(+), 24 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacet.java
index cd559d8..dad05a7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacet.java
@@ -19,7 +19,6 @@
 package org.apache.isis.core.metamodel.facets.object.objectspecid;
 
 
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 
 
@@ -28,6 +27,6 @@ import org.apache.isis.core.metamodel.facetapi.Facet;
  */
 public interface ObjectSpecIdFacet extends Facet {
 
-    ObjectSpecId value();
+    String value();
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetAbstract.java
index ad86b0d..f8e8f09 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetAbstract.java
@@ -21,33 +21,26 @@ package org.apache.isis.core.metamodel.facets.object.objectspecid;
 
 import java.util.Map;
 
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 
-public abstract class ObjectSpecIdFacetAbstract extends
-FacetAbstract implements ObjectSpecIdFacet {
+public abstract class ObjectSpecIdFacetAbstract
+extends FacetAbstract 
+implements ObjectSpecIdFacet {
 
     public static Class<? extends Facet> type() {
         return ObjectSpecIdFacet.class;
     }
 
-    private final ObjectSpecId value;
+    private final String value;
 
     public ObjectSpecIdFacetAbstract(final String value, final FacetHolder holder) {
         this(value, holder, Derivation.NOT_DERIVED);
     }
 
-    public ObjectSpecIdFacetAbstract(
-            final String value,
-            final FacetHolder holder,
-            final Derivation derivation) {
-        this(ObjectSpecId.of(value), holder, derivation);
-    }
-
     protected ObjectSpecIdFacetAbstract(
-            final ObjectSpecId value,
+            final String value,
             final FacetHolder holder,
             final Derivation derivation) {
         super(ObjectSpecIdFacetAbstract.type(), holder, derivation);
@@ -55,11 +48,12 @@ FacetAbstract implements ObjectSpecIdFacet {
     }
 
     @Override
-    public ObjectSpecId value() {
+    public String value() {
         return value;
     }
 
-    @Override public void appendAttributesTo(final Map<String, Object> attributeMap) {
+    @Override 
+    public void appendAttributesTo(final Map<String, Object> attributeMap) {
         super.appendAttributesTo(attributeMap);
         attributeMap.put("value", value);
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetOnStandaloneList.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetOnStandaloneList.java
index e57718b..3534a55 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetOnStandaloneList.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetOnStandaloneList.java
@@ -19,13 +19,12 @@
 
 package org.apache.isis.core.metamodel.facets.object.objectspecid.classname;
 
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacetAbstract;
 
 public class ObjectSpecIdFacetOnStandaloneList extends ObjectSpecIdFacetAbstract {
 
-    public ObjectSpecIdFacetOnStandaloneList(final ObjectSpecId value, final FacetHolder holder) {
+    public ObjectSpecIdFacetOnStandaloneList(final String value, final FacetHolder holder) {
         super(value, holder, Derivation.NOT_DERIVED);
     }
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
index 13826b0..918ffd8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
@@ -71,7 +71,9 @@ public class MetaModelServiceDefault implements MetaModelService {
             return null;
         }
         final ObjectSpecification objectSpecification = specificationLoader.lookupBySpecIdElseLoad(objectType);
-        return objectSpecification != null? objectSpecification.getCorrespondingClass(): null;
+        return objectSpecification != null
+                ? objectSpecification.getCorrespondingClass()
+                : null;
     }
 
     @Override
@@ -81,8 +83,7 @@ public class MetaModelServiceDefault implements MetaModelService {
         }
         final ObjectSpecification objectSpecification = specificationLoader.loadSpecification(domainType);
         final ObjectSpecIdFacet objectSpecIdFacet = objectSpecification.getFacet(ObjectSpecIdFacet.class);
-        final ObjectSpecId objectSpecId = objectSpecIdFacet.value();
-        return objectSpecId.asString();
+        return objectSpecIdFacet.value();
     }
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
index 17bc46a..34ccc65 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
@@ -237,7 +237,7 @@ implements ObjectSpecification {
         if(objectSpecIdFacet == null) {
             throw new IllegalStateException("could not find an ObjectSpecIdFacet for " + this.getFullIdentifier());
         }
-        return LogicalType.eager(correspondingClass, objectSpecIdFacet.value().asString());
+        return LogicalType.eager(correspondingClass, objectSpecIdFacet.value());
     }
 
     /**
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
index c0f2881..2fefd9b 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
@@ -132,7 +132,7 @@ implements ObjectSpecification {
     @Override
     public LogicalType getLogicalType() {
         if(logicalType == null) {
-            val logicalTypeName = getFacet(ObjectSpecIdFacet.class).value().asString();
+            val logicalTypeName = getFacet(ObjectSpecIdFacet.class).value();
             logicalType = LogicalType.eager(correspondingClass, logicalTypeName);
         }
         return logicalType;
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/Generation.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/Generation.java
index 5aca682..cf69371 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/Generation.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/Generation.java
@@ -761,7 +761,7 @@ class Generation {
     }
 
     static String objectTypeFor(final ObjectSpecification objectSpec) {
-        return objectSpec.getFacet(ObjectSpecIdFacet.class).value().asString();
+        return objectSpec.getFacet(ObjectSpecIdFacet.class).value();
     }
 
     static StringProperty stringProperty() {


[isis] 03/11: ISIS-2553: using LogicalType instead of ObjectSpedId (1st iteration)

Posted by ah...@apache.org.
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

commit 0fe22fba57ef0a840dfb237b5259665b1a5efbfc
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Mar 1 17:14:39 2021 +0100

    ISIS-2553: using LogicalType instead of ObjectSpedId (1st iteration)
---
 .../java/org/apache/isis/applib/Identifier.java    | 26 +++++----
 .../org/apache/isis/applib/id/HasLogicalType.java  | 15 ++---
 .../id/{TypeIdentifier.java => LogicalType.java}   | 30 +++++-----
 .../org/apache/isis/applib/id}/ObjectSpecId.java   | 10 ++--
 .../isis/applib/services/bookmark/Bookmark.java    | 35 +++++++-----
 .../org/apache/isis/applib/IdentifierTests.java    | 10 ++--
 .../isis/applib/events/InteractionEventTest.java   |  4 +-
 .../apache/isis/applib/id/TypeIdentifierTest.java  |  4 +-
 .../isis/core/metamodel/adapter/oid/Oid.java       | 33 ++++++-----
 .../core/metamodel/adapter/oid/Oid_Marshaller.java |  6 +-
 .../isis/core/metamodel/adapter/oid/Oid_Root.java  | 55 ++++++-------------
 .../isis/core/metamodel/adapter/oid/Oid_Value.java |  3 +-
 .../isis/core/metamodel/adapter/oid/RootOid.java   |  2 +-
 .../isis/core/metamodel/facetapi/FeatureType.java  | 18 +++---
 .../isis/core/metamodel/facets/FacetedMethod.java  |  4 +-
 .../metamodel/facets/FacetedMethodParameter.java   |  4 +-
 .../ViewModelSemanticCheckingFacetFactory.java     | 10 ++--
 .../DomainObjectAnnotationFacetFactory.java        |  6 +-
 .../mixin/MetaModelValidatorForMixinTypes.java     |  6 +-
 .../object/objectspecid/ObjectSpecIdFacet.java     |  2 +-
 .../objectspecid/ObjectSpecIdFacetAbstract.java    |  2 +-
 .../ObjectSpecIdFacetOnStandaloneList.java         |  2 +-
 .../identify/ObjectIdentifier_builtinHandlers.java |  8 +--
 .../services/appfeat/ApplicationFeatureId.java     |  5 +-
 .../metamodel/MetaModelServiceDefault.java         |  7 +--
 .../title/TitlesAndTranslationsValidator.java      | 10 ++--
 .../isis/core/metamodel/spec/ManagedObjects.java   |  3 +-
 .../core/metamodel/spec/ObjectSpecification.java   | 13 ++++-
 ...ClassResolver.java => LogicalTypeResolver.java} |  6 +-
 ...efault.java => LogicalTypeResolverDefault.java} | 14 ++---
 .../metamodel/specloader/SpecificationLoader.java  | 49 ++++++++++++-----
 .../specloader/SpecificationLoaderDefault.java     | 33 +++++------
 .../specloader/specimpl/ObjectActionMixedIn.java   |  4 +-
 .../specimpl/ObjectSpecificationAbstract.java      | 15 +++--
 .../specimpl/OneToManyAssociationMixedIn.java      |  4 +-
 .../specimpl/OneToOneAssociationMixedIn.java       |  4 +-
 .../specimpl/dflt/ObjectSpecificationDefault.java  |  2 +-
 .../adapter/oid/LogicalTypeTestFactory.java        | 21 ++++---
 .../adapter/oid/OidMarshallerTest_marshall.java    |  4 +-
 .../oid/OidMarshallerTest_roundtripping.java       |  6 +-
 .../adapter/oid/OidMarshallerTest_unmarshal.java   |  8 +--
 .../core/metamodel/adapter/oid/OidVersionTest.java | 18 +++---
 ...dDefaultTest_valueSemantics_whenPersistent.java | 14 ++---
 .../metamodel/adapter/oid/RootOidTest_create.java  |  9 ++-
 .../facetapi/FeatureTypeTest_identifierFor.java    |  6 +-
 .../facets/AbstractFacetFactoryJUnit4TestCase.java |  4 +-
 .../metamodel/facets/AbstractFacetFactoryTest.java |  4 +-
 ...nEventHelperTest_newActionInteractionEvent.java |  8 +--
 ...HelperTest_newCollectionDomainEvent_forAdd.java |  8 +--
 ...perTest_newCollectionDomainEvent_forRemove.java |  8 +--
 ...HelperTest_newPropertyDomainEvent_forClear.java |  6 +-
 ...elperTest_newPropertyDomainEvent_forModify.java |  6 +-
 .../DomainObjectAnnotationFacetFactoryTest.java    |  2 +-
 .../ObjectTypeAnnotationFacetFactoryTest.java      |  2 +-
 .../facets/object/mixin/MixinIntendedAs.java       |  4 +-
 ...SpecIdFacetDerivedFromClassNameFactoryTest.java |  2 +-
 .../metamodel/id/TypeIdentifierTestFactory.java    |  6 +-
 .../spec/ObjectSpecIdTest_constructor.java         |  2 +
 .../spec/ObjectSpecIdTest_valueSemantics.java      |  1 +
 .../specloader/SpecificationCacheDefaultTest.java  | 18 +++---
 .../testspec/ObjectSpecificationStub.java          | 24 ++++----
 .../isis/core/runtime/memento/ObjectMemento.java   | 18 +++---
 .../runtime/memento/ObjectMementoCollection.java   |  7 ++-
 .../runtime/memento/ObjectMementoForEmpty.java     | 10 ++--
 .../core/runtime/memento/ObjectMementoService.java |  6 +-
 .../bookmarks/BookmarkServiceDefault.java          |  3 +-
 .../command/CommandExecutorServiceDefault.java     |  2 +-
 .../AbstractRoleAndPermissionsFixtureScript.java   |  2 +-
 .../component/FullCalendarWithEventHandling.java   |  2 +-
 .../metamodel/facets/entity/JdoEntityFacet.java    |  2 +-
 .../object/query/VisitorForClauseAbstract.java     |  7 +--
 .../facets/object/query/VisitorForFromClause.java  |  7 +--
 .../object/query/VisitorForVariablesClause.java    |  7 +--
 ...JdoDiscriminatorAnnotationFacetFactoryTest.java |  2 +-
 .../object/version/TypeIdentifierTestFactory.java  |  6 +-
 .../testing/AbstractFacetFactoryTest.java          |  4 +-
 .../testdomain/domainmodel/SpecLoaderTest.java     |  6 +-
 .../shiro/authorization/AuthorizorShiro.java       |  2 +-
 .../security/shiro/TypeIdentifierTestFactory.java  | 10 ++--
 .../common/model/mementos/ActionMemento.java       |  4 +-
 .../common/model/menu/MenuUiModelProvider.java     |  2 +-
 .../domainobjects/DomainObjectReprRenderer.java    |  9 ++-
 .../rendering/domainobjects/JsonValueEncoder.java  |  2 +-
 .../JsonValueEncoderTest_appendValueAndFormat.java |  2 +-
 .../JsonValueEncoderTest_asAdapter.java            |  2 +-
 .../JsonValueEncoderTest_asObject.java             |  2 +-
 .../resources/DomainObjectResourceServerside.java  |  7 +--
 .../resources/DomainTypeResourceServerside.java    | 21 ++++---
 .../viewer/wicket/model/links/LinkAndLabel.java    |  8 +--
 .../wicket/model/mementos/CollectionMemento.java   |  8 +--
 .../wicket/model/mementos/PropertyMemento.java     | 36 ++++++------
 .../model/models/BookmarkTreeNodeComparator.java   |  4 +-
 .../wicket/model/models/ManagedObjectModel.java    | 10 ++--
 .../wicket/model/models/PageParameterUtil.java     |  2 +-
 .../viewer/wicket/model/models/ScalarModel.java    |  7 ++-
 .../model/models/ScalarModelWithMultiPending.java  |  9 ++-
 .../bookmarkedpages/BookmarkedPagesPanel.java      |  5 +-
 .../scalars/ScalarPanelSelectAbstract.java         |  4 +-
 .../ui/components/widgets/select2/ChoiceExt.java   |  8 +--
 .../ui/components/widgets/select2/Select2.java     |  6 +-
 .../widgets/select2/Select2ChoiceExt.java          | 16 +++---
 .../widgets/select2/Select2MultiChoiceExt.java     | 15 ++---
 .../ObjectAdapterMementoProviderAbstract.java      |  6 +-
 ...tAdapterMementoProviderForValueChoicesTest.java | 20 ++++---
 .../integration/ConverterForObjectAdapter.java     |  3 +-
 .../mementos/ObjectMementoServiceWicket.java       | 22 ++++----
 .../viewer/services/mementos/ObjectMementoWkt.java | 64 +++++++++++-----------
 107 files changed, 543 insertions(+), 519 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/Identifier.java b/api/applib/src/main/java/org/apache/isis/applib/Identifier.java
index 7253d89..bd287be 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/Identifier.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/Identifier.java
@@ -23,7 +23,8 @@ import java.io.Serializable;
 import java.util.Objects;
 import java.util.stream.Collectors;
 
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.HasLogicalType;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.base._Strings;
@@ -33,18 +34,19 @@ import lombok.NonNull;
 import lombok.val;
 
 /**
- * Combines {@link TypeIdentifier} and member identification (from properties, collections or actions),
+ * Combines {@link LogicalType} and member identification (from properties, collections or actions),
  * to a fully qualified <i>feature</i> identifier.
  * <p> 
  * For {@link Identifier}(s) of type {@link Identifier.Type#CLASS} member information is 
  * left empty.   
  *  
  * @since 1.x revised for 2.0 {@index}
- * @see TypeIdentifier
+ * @see LogicalType
  */
 public class Identifier 
 implements 
     Comparable<Identifier>,
+    HasLogicalType,
     Serializable {
 
     private static final long serialVersionUID = 1L;
@@ -61,26 +63,26 @@ implements
 
     // -- FACTORY METHODS
 
-    public static Identifier classIdentifier(final TypeIdentifier typeIdentifier) {
+    public static Identifier classIdentifier(final LogicalType typeIdentifier) {
         return new Identifier(typeIdentifier, "", Can.empty(), Type.CLASS);
     }
 
     public static Identifier propertyOrCollectionIdentifier(
-            final TypeIdentifier typeIdentifier,
+            final LogicalType typeIdentifier,
             final String propertyOrCollectionName) {
         return new Identifier(typeIdentifier, propertyOrCollectionName, Can.empty(), 
                 Type.PROPERTY_OR_COLLECTION);
     }
 
     public static Identifier actionIdentifier(
-            final TypeIdentifier typeIdentifier,
+            final LogicalType typeIdentifier,
             final String actionName, 
             final Class<?>... parameterClasses) {
         return actionIdentifier(typeIdentifier, actionName, classNamesOf(parameterClasses));
     }
 
     public static Identifier actionIdentifier(
-            final TypeIdentifier typeIdentifier,
+            final LogicalType typeIdentifier,
             final String actionName, 
             final Can<String> parameterClassNames) {
         return new Identifier(typeIdentifier, actionName, parameterClassNames, Type.ACTION);
@@ -88,7 +90,7 @@ implements
 
     // -- INSTANCE FIELDS
 
-    @Getter private final TypeIdentifier typeIdentifier;
+    @Getter(onMethod_ = {@Override}) private final LogicalType logicalType;
     
     @Getter private final String className;
     
@@ -117,13 +119,13 @@ implements
     // -- CONSTRUCTOR
 
     private Identifier(
-            final TypeIdentifier typeIdentifier,
+            final LogicalType logicalType,
             final String memberName, 
             final Can<String> memberParameterClassNames, 
             final Type type) {
         
-        this.typeIdentifier = typeIdentifier;
-        this.className = typeIdentifier.getClassName();
+        this.logicalType = logicalType;
+        this.className = logicalType.getClassName();
         this.memberName = memberName;
         this.memberParameterClassNames = memberParameterClassNames;
         this.type = type;
@@ -144,7 +146,7 @@ implements
     // -- LOGICAL ID
     
     public String getLogicalIdentityString(final @NonNull String delimiter) {
-        return typeIdentifier.getLogicalTypeName() 
+        return getLogicalTypeName() 
                 + delimiter 
                 + memberNameAndParameterClassNamesIdentityString;
     }
diff --git a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/TypeIdentifierTestFactory.java b/api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java
similarity index 74%
copy from persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/TypeIdentifierTestFactory.java
copy to api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java
index 22a3868..5e0523a 100644
--- a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/TypeIdentifierTestFactory.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/id/HasLogicalType.java
@@ -16,16 +16,17 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.persistence.jdo.metamodel.facets.object.version;
+package org.apache.isis.applib.id;
 
-import org.apache.isis.applib.id.TypeIdentifier;
-
-final class TypeIdentifierTestFactory {
+/**
+ * @since 2.0 {@index}
+ */
+public interface HasLogicalType {
 
-    private static class Customer {};
+    LogicalType getLogicalType();
     
-    static TypeIdentifier customer() {
-        return TypeIdentifier.fqcn(Customer.class);
+    default String getLogicalTypeName() {
+        return getLogicalType().getLogicalTypeName();
     }
     
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/id/TypeIdentifier.java b/api/applib/src/main/java/org/apache/isis/applib/id/LogicalType.java
similarity index 90%
rename from api/applib/src/main/java/org/apache/isis/applib/id/TypeIdentifier.java
rename to api/applib/src/main/java/org/apache/isis/applib/id/LogicalType.java
index a925402..360f1e8 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/id/TypeIdentifier.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/id/LogicalType.java
@@ -41,9 +41,9 @@ import lombok.val;
  * @since 2.0 {@index}
  */
 @ToString
-public final class TypeIdentifier 
+public final class LogicalType 
 implements 
-    Comparable<TypeIdentifier>,
+    Comparable<LogicalType>,
     Serializable {
     
     private static final long serialVersionUID = 1L;
@@ -66,29 +66,29 @@ implements
      * Returns a new TypeIdentifier based on the corresponding class
      * and a {@code logicalNameProvider} for lazy logical name lookup.  
      */
-    public static TypeIdentifier lazy(
+    public static LogicalType lazy(
             final @NonNull Class<?> correspondingClass, 
             final @NonNull Supplier<String> logicalNameProvider) {
         
-        return new TypeIdentifier(correspondingClass, logicalNameProvider);
+        return new LogicalType(correspondingClass, logicalNameProvider);
     }
     
     /**
      * Returns a new TypeIdentifier based on the corresponding class
      * and (ahead of time) known {@code logicalName}. 
      */
-    public static TypeIdentifier eager(
+    public static LogicalType eager(
             final @NonNull Class<?> correspondingClass, 
             final String logicalName) {
         
-        return new TypeIdentifier(correspondingClass, logicalName);
+        return new LogicalType(correspondingClass, logicalName);
     }
     
     /**
      * Use the corresponding class's fully qualified name for the {@code logicalName}. 
      * Most likely used in testing scenarios.
      */
-    public static TypeIdentifier fqcn(
+    public static LogicalType fqcn(
             final @NonNull Class<?> correspondingClass) {
         
         return eager(correspondingClass, correspondingClass.getName());
@@ -96,7 +96,7 @@ implements
     
     // -- HIDDEN CONSTRUTORS
     
-    private TypeIdentifier(
+    private LogicalType(
             final @NonNull Class<?> correspondingClass, 
             final @NonNull Supplier<String> logicalNameProvider) {
         
@@ -104,7 +104,7 @@ implements
         this.logicalNameProvider = logicalNameProvider;
     }
     
-    private TypeIdentifier(
+    private LogicalType(
             final @NonNull Class<?> correspondingClass, 
             final String logicalName) {
         
@@ -185,13 +185,13 @@ implements
         if (this == obj) {
             return true;
         }
-        if (obj instanceof TypeIdentifier) {
-            return isEqualTo((TypeIdentifier) obj);
+        if (obj instanceof LogicalType) {
+            return isEqualTo((LogicalType) obj);
         }
         return false;
     }
     
-    public boolean isEqualTo(final @Nullable TypeIdentifier other) {
+    public boolean isEqualTo(final @Nullable LogicalType other) {
         if(other==null) {
             return false;
         }
@@ -204,7 +204,7 @@ implements
     }
 
     @Override
-    public int compareTo(final @Nullable TypeIdentifier other) {
+    public int compareTo(final @Nullable LogicalType other) {
         val otherClassName = other!=null
                 ? other.getCorrespondingClass().getCanonicalName()
                 : null;
@@ -226,13 +226,13 @@ implements
         private final @NonNull Class<?> correspondingClass;
         private final @NonNull String logicalTypeName;
         
-        private SerializationProxy(TypeIdentifier typeIdentifier) {
+        private SerializationProxy(LogicalType typeIdentifier) {
             this.correspondingClass = typeIdentifier.getCorrespondingClass();
             this.logicalTypeName = typeIdentifier.getLogicalTypeName();
         }
 
         private Object readResolve() {
-            return TypeIdentifier.eager(correspondingClass, logicalTypeName);
+            return LogicalType.eager(correspondingClass, logicalTypeName);
         }
     }
     
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecId.java b/api/applib/src/main/java/org/apache/isis/applib/id/ObjectSpecId.java
similarity index 84%
rename from core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecId.java
rename to api/applib/src/main/java/org/apache/isis/applib/id/ObjectSpecId.java
index d64ffce..ba9d81b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecId.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/id/ObjectSpecId.java
@@ -16,13 +16,11 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.metamodel.spec;
+package org.apache.isis.applib.id;
 
 import java.io.Serializable;
 
-import org.apache.isis.applib.id.TypeIdentifier;
 import org.apache.isis.commons.internal.base._Refs;
-import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
 
 import static org.apache.isis.commons.internal.base._With.requiresNotEmpty;
 
@@ -32,12 +30,12 @@ import lombok.RequiredArgsConstructor;
 import lombok.Value;
 
 /**
- * Represents an {@link ObjectSpecification}, as determined by
- * an {@link ObjectSpecIdFacet}.
+ * Represents an {@link org.apache.isis.core.metamodel.spec.ObjectSpecification}, as determined by
+ * an {@link org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet}.
  *
  * <p>
  * Has value semantics.
- * @deprecated use {@link TypeIdentifier} instead
+ * @deprecated use {@link LogicalType} instead
  */
 @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
 @Value
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/Bookmark.java b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/Bookmark.java
index 6c87837..f26a757 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/Bookmark.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/Bookmark.java
@@ -44,27 +44,23 @@ import lombok.val;
 @lombok.Value @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
 public class Bookmark implements Serializable {
 
-    private static final long serialVersionUID = 2L;
+    private static final long serialVersionUID = 3L;
 
     protected static final String SEPARATOR = ":";
 
     /**
-     * corresponds directly to the object's specification-id
+     * Corresponds directly to the object's logical-type-name (aka. object-type).
      * @see RootOid
      */
-    @NonNull  private final String objectType;
+    @NonNull  private final String logicalTypeName;
     @NonNull  private final String identifier;
 
     @Nullable private final String hintId;
 
-    public static Bookmark of(String objectType, String identifier) {
-
-        return new Bookmark(objectType, identifier, /*hintId*/ null);
-
-        // ...
+    public static Bookmark of(String logicalTypeName, String identifier) {
+        return new Bookmark(logicalTypeName, identifier, /*hintId*/ null);
     }
 
-
     /**
      * Round-trip with {@link #toString()} representation.
      */
@@ -88,7 +84,7 @@ public class Bookmark implements Serializable {
 
     public OidDto toOidDto() {
         val oidDto = new OidDto();
-        oidDto.setType(getObjectType());
+        oidDto.setType(getLogicalTypeName());
         oidDto.setId(getIdentifier());
         return oidDto;
     }
@@ -99,23 +95,32 @@ public class Bookmark implements Serializable {
     
     /**
      * The canonical form of the {@link Bookmark}, that is 
-     * &quot;{@link #getObjectType() objectType}{@value #SEPARATOR}{@link #getIdentifier()}&quot;.
+     * &quot;{@link #getLogicalTypeName() logical-type-name}{@value #SEPARATOR}{@link #getIdentifier()}&quot;.
      *
      * <p>
      * This is parseable by the {@link #parse(String)}.
      */
     @Override
     public String toString() {
-        return objectType + SEPARATOR + identifier;
+        return toStringUsingIdentifier(identifier);
     }
 
-
     public Bookmark withHintId(@NonNull String hintId) {
-        return new Bookmark(this.getObjectType(), this.getIdentifier(), hintId); 
+        return new Bookmark(this.getLogicalTypeName(), this.getIdentifier(), hintId); 
     }
 
     public String toStringUsingIdentifier(String id) {
-        return objectType + SEPARATOR + id;
+        return logicalTypeName + SEPARATOR + id;
     }
+    
+    // -- DEPRECATIONS 
+    
+    /**
+     * @deprecated use {@link #getLogicalTypeName()} instead
+     */
+    public String getObjectType() {
+        return getLogicalTypeName();
+    }
+    
 
 }
diff --git a/api/applib/src/test/java/org/apache/isis/applib/IdentifierTests.java b/api/applib/src/test/java/org/apache/isis/applib/IdentifierTests.java
index 810c6d4..4a52aaa 100644
--- a/api/applib/src/test/java/org/apache/isis/applib/IdentifierTests.java
+++ b/api/applib/src/test/java/org/apache/isis/applib/IdentifierTests.java
@@ -29,7 +29,7 @@ import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.collections.Can;
 
 public class IdentifierTests {
@@ -42,7 +42,7 @@ public class IdentifierTests {
 
     @Test
     public void canInstantiateClassIdentifier() {
-        identifier = Identifier.classIdentifier(TypeIdentifier.fqcn(SomeDomainClass.class));
+        identifier = Identifier.classIdentifier(LogicalType.fqcn(SomeDomainClass.class));
         assertThat(identifier, is(not(nullValue())));
     }
 
@@ -50,21 +50,21 @@ public class IdentifierTests {
     public void classIdentifierClassNameIsSet() {
         final Class<?> domainClass = SomeDomainClass.class;
         final String domainClassFullyQualifiedName = domainClass.getCanonicalName();
-        identifier = Identifier.classIdentifier(TypeIdentifier.fqcn(domainClass));
+        identifier = Identifier.classIdentifier(LogicalType.fqcn(domainClass));
         assertThat(identifier.getClassName(), is(domainClassFullyQualifiedName));
     }
 
     @Test
     public void memberParameterNames() {
         final Class<?> domainClass = SomeDomainClass.class;
-        identifier = Identifier.actionIdentifier(TypeIdentifier.fqcn(domainClass), "placeOrder", int.class, String.class);
+        identifier = Identifier.actionIdentifier(LogicalType.fqcn(domainClass), "placeOrder", int.class, String.class);
         assertThat(identifier.getMemberParameterClassNames(), is(Can.of("int", "java.lang.String")));
     }
 
     @Test
     public void paramsIdentityString() {
         final Class<?> domainClass = SomeDomainClass.class;
-        identifier = Identifier.actionIdentifier(TypeIdentifier.fqcn(domainClass), "placeOrder", int.class, String.class, BigDecimal.class);
+        identifier = Identifier.actionIdentifier(LogicalType.fqcn(domainClass), "placeOrder", int.class, String.class, BigDecimal.class);
         assertThat(
                 identifier.getFullIdentityString(), 
                 is("org.apache.isis.applib.SomeDomainClass#placeOrder(int,java.lang.String,java.math.BigDecimal)"));
diff --git a/api/applib/src/test/java/org/apache/isis/applib/events/InteractionEventTest.java b/api/applib/src/test/java/org/apache/isis/applib/events/InteractionEventTest.java
index 1604ed1..8e70ad2 100644
--- a/api/applib/src/test/java/org/apache/isis/applib/events/InteractionEventTest.java
+++ b/api/applib/src/test/java/org/apache/isis/applib/events/InteractionEventTest.java
@@ -30,7 +30,7 @@ import static org.junit.Assert.assertEquals;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.wrapper.events.InteractionEvent;
 
 public class InteractionEventTest {
@@ -51,7 +51,7 @@ public class InteractionEventTest {
     public void setUp() {
         source = new Object();
         identifier = Identifier.actionIdentifier(
-                TypeIdentifier.fqcn(CustomerOrder.class), 
+                LogicalType.fqcn(CustomerOrder.class), 
                 "cancelOrder", new Class[] { String.class, boolean.class });
         advisorClass = this.getClass();
     }
diff --git a/api/applib/src/test/java/org/apache/isis/applib/id/TypeIdentifierTest.java b/api/applib/src/test/java/org/apache/isis/applib/id/TypeIdentifierTest.java
index 9f6b344..6698d61 100644
--- a/api/applib/src/test/java/org/apache/isis/applib/id/TypeIdentifierTest.java
+++ b/api/applib/src/test/java/org/apache/isis/applib/id/TypeIdentifierTest.java
@@ -37,7 +37,7 @@ class TypeIdentifierTest {
     @Test
     void eager() {
         
-        val original = TypeIdentifier.fqcn(SomeDomainClass.class);
+        val original = LogicalType.fqcn(SomeDomainClass.class);
         
         _SerializationTester.assertEqualsOnRoundtrip(original);
         
@@ -53,7 +53,7 @@ class TypeIdentifierTest {
     @Test
     void lazy() {
         
-        val original = TypeIdentifier.lazy(SomeDomainClass.class, ()->"hello");
+        val original = LogicalType.lazy(SomeDomainClass.class, ()->"hello");
         
         _SerializationTester.assertEqualsOnRoundtrip(original);
         
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java
index 7738c67..c884b4e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java
@@ -22,8 +22,8 @@ package org.apache.isis.core.metamodel.adapter.oid;
 import java.io.Serializable;
 
 import org.apache.isis.applib.annotation.Value;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.schema.common.v2.OidDto;
 
 /**
@@ -46,19 +46,16 @@ public interface Oid extends Serializable {
     }
     
     /**
-     * {@link ObjectSpecId} of the domain object this instance is representing, or when parented,
-     * the ObjectSpecId of the parent domain object. When representing a value returns {@code null}.   
+     * The logical-type-name of the domain object this instance is representing.
+     * When representing a value returns {@code null}.
      */
-    ObjectSpecId getObjectSpecId();
+    String getLogicalTypeName();
 
     // -- MARSHALLING
 
     public static interface Marshaller {
-
         String marshal(RootOid rootOid);
-
-        String joinAsOid(String domainType, String instanceId);
-
+        String joinAsOid(String logicalTypeName, String instanceId);
     }
 
     public static Marshaller marshaller() {
@@ -68,11 +65,8 @@ public interface Oid extends Serializable {
     // -- UN-MARSHALLING
 
     public static interface Unmarshaller {
-
         <T extends Oid> T unmarshal(String oidStr, Class<T> requestedType);
-
         String splitInstanceId(String oidStr);
-
     }
 
     public static Unmarshaller unmarshaller() {
@@ -90,18 +84,27 @@ public interface Oid extends Serializable {
 
         public static RootOid ofBookmark(final Bookmark bookmark) {
             return Oid_Root.of(
-                    ObjectSpecId.of(bookmark.getObjectType()), 
+                    bookmark.getLogicalTypeName(), 
                     bookmark.getIdentifier());
         }
         
         public static RootOid ofDto(final OidDto oid) {
             return Oid_Root.of(
-                    ObjectSpecId.of(oid.getType()), 
+                    oid.getType(), 
                     oid.getId());
         }
 
-        public static RootOid root(final ObjectSpecId objectSpecId, final String identifier) {
-            return Oid_Root.of(objectSpecId, identifier);
+        public static RootOid root(final LogicalType logicalType, final String identifier) {
+            return Oid_Root.of(
+                    logicalType.getLogicalTypeName(), 
+                    identifier);
+        }
+        
+        @Deprecated
+        public static RootOid root(final String logicalTypeName, final String identifier) {
+            return Oid_Root.of(
+                    logicalTypeName, 
+                    identifier);
         }
         
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Marshaller.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Marshaller.java
index 3ce264d..1e0a10e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Marshaller.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Marshaller.java
@@ -20,7 +20,6 @@ package org.apache.isis.core.metamodel.adapter.oid;
 
 import java.util.Iterator;
 import java.util.List;
-import java.util.Objects;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Stream;
@@ -30,7 +29,6 @@ import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 
 import static org.apache.isis.commons.internal.base._Strings.splitThenStream;
 
@@ -176,7 +174,7 @@ final class Oid_Marshaller implements Oid.Marshaller, Oid.Unmarshaller {
             if(aggregateOidParts.isEmpty()) {
                 ensureCorrectType(oidStr, requestedType, RootOid.class);
                 return _Casts.uncheckedCast(
-                        Oid_Root.of(ObjectSpecId.of(rootObjectType), rootIdentifier));
+                        Oid_Root.of(rootObjectType, rootIdentifier));
             } else {
                 throw _Exceptions.illegalArgument("Aggregated OIDs are no longer supported");
             }
@@ -224,7 +222,7 @@ final class Oid_Marshaller implements Oid.Marshaller, Oid.Unmarshaller {
     @Override
     public final String marshal(RootOid rootOid) {
         _Assert.assertFalse(rootOid.isValue(), "cannot marshal values");
-        return rootOid.getObjectSpecId() + SEPARATOR + rootOid.getIdentifier();
+        return rootOid.getLogicalTypeName() + SEPARATOR + rootOid.getIdentifier();
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Root.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Root.java
index 6d338e5..f81ad21 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Root.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Root.java
@@ -23,40 +23,39 @@ import java.util.Objects;
 
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.commons.internal.codec._UrlDecoderUtil;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.schema.common.v2.OidDto;
 
-import static org.apache.isis.commons.internal.base._With.requires;
-
+import lombok.Getter;
+import lombok.NonNull;
 import lombok.val;
 
 final class Oid_Root implements RootOid {
 
     private static final long serialVersionUID = 3L;
 
-    private final ObjectSpecId objectSpecId;
-    private final String identifier;
+    @Getter(onMethod_ = {@Override}) private final String logicalTypeName;
+    @Getter(onMethod_ = {@Override}) private final String identifier;
+    
     private final int hashCode;
 
     public static Oid_Root of(
-            ObjectSpecId objectSpecId, 
-            String identifier) {
-
-        return new Oid_Root(objectSpecId, identifier);
+            final @NonNull String logicalTypeName, 
+            final @NonNull String identifier) {
+        return new Oid_Root(logicalTypeName, identifier);
     }
 
-    private Oid_Root(ObjectSpecId objectSpecId, String identifier) {
+    private Oid_Root(
+            final String logicalTypeName, 
+            final String identifier) {
 
-        requires(objectSpecId, "objectSpecId");
-        requires(identifier, "identifier");
-
-        this.objectSpecId = objectSpecId;
+        this.logicalTypeName = logicalTypeName;
         this.identifier = identifier;
         this.hashCode = calculateHash();
 
     }
 
-    // -- deString'able, enString
+    // -- ENCODING 
+    
     public static Oid_Root deStringEncoded(final String urlEncodedOidStr) {
         final String oidStr = _UrlDecoderUtil.urlDecode(urlEncodedOidStr);
         return deString(oidStr);
@@ -71,36 +70,19 @@ final class Oid_Root implements RootOid {
         return Oid.marshaller().marshal(this);
     }
 
-    // -- Properties
-    @Override
-    public ObjectSpecId getObjectSpecId() {
-        return objectSpecId;
-    }
-
-    @Override
-    public String getIdentifier() {
-        return identifier;
-    }
-
     @Override
     public Bookmark asBookmark() {
-        val objectType = getObjectSpecId().asString();
-        val identifier = getIdentifier();
-        return Bookmark.of(objectType, identifier);
+        return Bookmark.of(logicalTypeName, getIdentifier());
     }
 
     @Override
     public OidDto asOidDto() {
-
         val oidDto = new OidDto();
-
-        oidDto.setType(getObjectSpecId().asString());
+        oidDto.setType(logicalTypeName);
         oidDto.setId(getIdentifier());
-
         return oidDto;
     }
 
-
     @Override
     public boolean equals(final Object other) {
         if (other == null) {
@@ -116,7 +98,7 @@ final class Oid_Root implements RootOid {
     }
 
     public boolean equals(final Oid_Root other) {
-        return Objects.equals(objectSpecId, other.getObjectSpecId()) 
+        return Objects.equals(logicalTypeName, other.getLogicalTypeName()) 
                 && Objects.equals(identifier, other.getIdentifier());
     }
 
@@ -133,8 +115,7 @@ final class Oid_Root implements RootOid {
     // -- HELPER
 
     private int calculateHash() {
-        return Objects.hash(objectSpecId, identifier);
+        return Objects.hash(logicalTypeName, identifier);
     }
 
-
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Value.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Value.java
index ed116a5..7b620ff 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Value.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Value.java
@@ -20,7 +20,6 @@
 package org.apache.isis.core.metamodel.adapter.oid;
 
 import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.schema.common.v2.OidDto;
 
 final class Oid_Value implements RootOid {
@@ -40,7 +39,7 @@ final class Oid_Value implements RootOid {
     }
 
     @Override
-    public ObjectSpecId getObjectSpecId() {
+    public String getLogicalTypeName() {
         return null;
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/RootOid.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/RootOid.java
index 7ce0b30..2128207 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/RootOid.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/RootOid.java
@@ -53,7 +53,7 @@ public interface RootOid extends Oid {
     default public ManagedObject loadObject(SpecificationLoader specificationLoader) {
         val mmc = ((SpecificationLoaderDefault)specificationLoader).getMetaModelContext();
 
-        val spec = specificationLoader.loadSpecification(this.getObjectSpecId());
+        val spec = specificationLoader.loadSpecification(this.getLogicalTypeName());
         val objectId = this.getIdentifier();
 
         val objectLoadRequest = ObjectLoader.Request.of(spec, objectId);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FeatureType.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FeatureType.java
index 6ffc8af..1c3e27d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FeatureType.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FeatureType.java
@@ -23,7 +23,7 @@ import java.beans.Introspector;
 import java.lang.reflect.Method;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.collections.ImmutableEnumSet;
 import org.apache.isis.core.metamodel.commons.StringExtensions;
 import org.apache.isis.core.metamodel.facets.FacetFactory;
@@ -43,25 +43,25 @@ public enum FeatureType {
          * The supplied method can be null; at any rate it will be ignored.
          */
         @Override
-        public Identifier identifierFor(final TypeIdentifier typeIdentifier, final Method method) {
+        public Identifier identifierFor(final LogicalType typeIdentifier, final Method method) {
             return Identifier.classIdentifier(typeIdentifier);
         }
     },
     PROPERTY("Property") {
         @Override
-        public Identifier identifierFor(final TypeIdentifier typeIdentifier, final Method method) {
+        public Identifier identifierFor(final LogicalType typeIdentifier, final Method method) {
             return propertyOrCollectionIdentifierFor(typeIdentifier, method);
         }
     },
     COLLECTION("Collection") {
         @Override
-        public Identifier identifierFor(final TypeIdentifier typeIdentifier, final Method method) {
+        public Identifier identifierFor(final LogicalType typeIdentifier, final Method method) {
             return propertyOrCollectionIdentifierFor(typeIdentifier, method);
         }
     },
     ACTION("Action") {
         @Override
-        public Identifier identifierFor(final TypeIdentifier typeIdentifier, final Method method) {
+        public Identifier identifierFor(final LogicalType typeIdentifier, final Method method) {
             final String fullMethodName = method.getName();
             final Class<?>[] parameterTypes = method.getParameterTypes();
             return Identifier.actionIdentifier(typeIdentifier, fullMethodName, parameterTypes);
@@ -72,7 +72,7 @@ public enum FeatureType {
          * Always returns <tt>null</tt>.
          */
         @Override
-        public Identifier identifierFor(final TypeIdentifier typeIdentifier, final Method method) {
+        public Identifier identifierFor(final LogicalType typeIdentifier, final Method method) {
             return null;
         }
     },
@@ -81,7 +81,7 @@ public enum FeatureType {
          * Always returns <tt>null</tt>.
          */
         @Override
-        public Identifier identifierFor(final TypeIdentifier typeIdentifier, final Method method) {
+        public Identifier identifierFor(final LogicalType typeIdentifier, final Method method) {
             return null;
         }
     };
@@ -121,7 +121,7 @@ public enum FeatureType {
     }
 
     private static Identifier propertyOrCollectionIdentifierFor(
-            final TypeIdentifier typeIdentifier, 
+            final LogicalType typeIdentifier, 
             final Method method) {
         
         final String capitalizedName = StringExtensions.asJavaBaseName(method.getName());
@@ -152,7 +152,7 @@ public enum FeatureType {
         return isProperty() || isCollection();
     }
 
-    public abstract Identifier identifierFor(TypeIdentifier typeIdentifier, Method method);
+    public abstract Identifier identifierFor(LogicalType typeIdentifier, Method method);
 
     @Override
     public String toString() {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethod.java
index 9bc6cb6..4de5a69 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethod.java
@@ -25,7 +25,7 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.internal.collections._Collections;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.commons.StringExtensions;
@@ -169,7 +169,7 @@ public class FacetedMethod extends TypedHolderDefault implements IdentifiedHolde
         this.owningType = declaringType;
         this.method = method;
         
-        val typeIdentifier = TypeIdentifier.lazy(
+        val typeIdentifier = LogicalType.lazy(
                 declaringType,
                 ()->getSpecificationLoader().loadSpecification(declaringType).getSpecId().asString());
         
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethodParameter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethodParameter.java
index ac7a0d8..1f3f15d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethodParameter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/FacetedMethodParameter.java
@@ -21,7 +21,7 @@ package org.apache.isis.core.metamodel.facets;
 import java.lang.reflect.Method;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
 
@@ -41,7 +41,7 @@ implements IdentifiedHolder {
         
         super(featureType, type);
         
-        val typeIdentifier = TypeIdentifier.lazy(
+        val typeIdentifier = LogicalType.lazy(
                 declaringType,
                 ()->getSpecificationLoader().loadSpecification(declaringType).getSpecId().asString());
         
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactory.java
index 664c3de..8640de7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.applib.RecreatableDomainObject;
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainObjectLayout;
 import org.apache.isis.applib.annotation.Nature;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
@@ -76,7 +76,7 @@ implements MetaModelRefiner {
         if(implementsViewModel && implementsRecreatableDomainObject) {
             validator.onFailure(
                     facetHolder,
-                    Identifier.classIdentifier(TypeIdentifier.fqcn(cls)),
+                    Identifier.classIdentifier(LogicalType.fqcn(cls)),
                     "Inconsistent view model / domain object semantics; %s should not implement "
                     + "both %s and %s interfaces (implement one or the other)",
                     cls.getName(),
@@ -87,7 +87,7 @@ implements MetaModelRefiner {
         if(implementsViewModel && annotatedWithDomainObject) {
             validator.onFailure(
                     facetHolder,
-                    Identifier.classIdentifier(TypeIdentifier.fqcn(cls)),
+                    Identifier.classIdentifier(LogicalType.fqcn(cls)),
                     "Inconsistent view model / domain object semantics; %1$s should not implement "
                     + "%2$s and be annotated with @%3$s (annotate with %4$s instead of %2$s, or implement %5s instead of %2$s)",
                     cls.getName(),
@@ -100,7 +100,7 @@ implements MetaModelRefiner {
         if(implementsViewModel && annotatedWithDomainObjectLayout) {
             validator.onFailure(
                     facetHolder,
-                    Identifier.classIdentifier(TypeIdentifier.fqcn(cls)),
+                    Identifier.classIdentifier(LogicalType.fqcn(cls)),
                     "Inconsistent view model / domain object semantics; %1$s should not implement "
                     + "%2$s and be annotated with @%3$s (annotate with @%4$s instead of %3$s, or implement %5$s instead of %2$s)",
                     cls.getName(),
@@ -115,7 +115,7 @@ implements MetaModelRefiner {
                 && implementsRecreatableDomainObject) {
             validator.onFailure(
                     facetHolder,
-                    Identifier.classIdentifier(TypeIdentifier.fqcn(cls)),
+                    Identifier.classIdentifier(LogicalType.fqcn(cls)),
                     "Inconsistent view model / domain object semantics; %1$s should not be annotated with "
                     + "@%2$s with nature of %3$s and also implement %4$s (specify a nature of %5$s)",
                     cls.getName(),
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
index 6467369..f43439e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
@@ -39,7 +39,8 @@ import org.apache.isis.applib.events.lifecycle.ObjectPersistingEvent;
 import org.apache.isis.applib.events.lifecycle.ObjectRemovingEvent;
 import org.apache.isis.applib.events.lifecycle.ObjectUpdatedEvent;
 import org.apache.isis.applib.events.lifecycle.ObjectUpdatingEvent;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.commons.having.HasUniqueId;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.collections._Multimaps;
@@ -74,7 +75,6 @@ import org.apache.isis.core.metamodel.facets.object.mixin.MetaModelValidatorForM
 import org.apache.isis.core.metamodel.facets.object.mixin.MixinFacetForDomainObjectAnnotation;
 import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidator;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForValidationFailures;
@@ -221,7 +221,7 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
         }
         autoCompleteMethodInvalid.onFailure(
                 facetHolder,
-                Identifier.classIdentifier(TypeIdentifier.fqcn(cls)),
+                Identifier.classIdentifier(LogicalType.fqcn(cls)),
                 "%s annotation on %s specifies method '%s' that does not exist in repository '%s'",
                 annotationName, cls.getName(), methodName, repositoryClass.getName());
         return null;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java
index 5d27005..34ee847 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java
@@ -19,7 +19,7 @@
 package org.apache.isis.core.metamodel.facets.object.mixin;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.internal.reflection._Reflect;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForValidationFailures;
@@ -52,14 +52,14 @@ public class MetaModelValidatorForMixinTypes extends MetaModelValidatorForValida
         if(mixinContructors.getCardinality().isZero()) {
             onFailure(
                     facetHolder,
-                    Identifier.classIdentifier(TypeIdentifier.fqcn(candidateMixinType)),
+                    Identifier.classIdentifier(LogicalType.fqcn(candidateMixinType)),
                     "%s: annotated with %s annotation but does not have a public 1-arg constructor",
                     candidateMixinType.getName(), 
                     annotation);
         } else {
             onFailure(
                     facetHolder,
-                    Identifier.classIdentifier(TypeIdentifier.fqcn(candidateMixinType)),
+                    Identifier.classIdentifier(LogicalType.fqcn(candidateMixinType)),
                     "%s: annotated with %s annotation needs a single public 1-arg constructor but has %d",
                     candidateMixinType.getName(), 
                     annotation,
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacet.java
index 18c5174..cd559d8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacet.java
@@ -19,8 +19,8 @@
 package org.apache.isis.core.metamodel.facets.object.objectspecid;
 
 
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.facetapi.Facet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 
 
 /**
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetAbstract.java
index acd36a3..ad86b0d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetAbstract.java
@@ -21,10 +21,10 @@ package org.apache.isis.core.metamodel.facets.object.objectspecid;
 
 import java.util.Map;
 
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 
 public abstract class ObjectSpecIdFacetAbstract extends
 FacetAbstract implements ObjectSpecIdFacet {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetOnStandaloneList.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetOnStandaloneList.java
index 680eec9..e57718b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetOnStandaloneList.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetOnStandaloneList.java
@@ -19,9 +19,9 @@
 
 package org.apache.isis.core.metamodel.facets.object.objectspecid.classname;
 
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacetAbstract;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 
 public class ObjectSpecIdFacetOnStandaloneList extends ObjectSpecIdFacetAbstract {
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectIdentifier_builtinHandlers.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectIdentifier_builtinHandlers.java
index efa7aa9..b7a2be5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectIdentifier_builtinHandlers.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectIdentifier_builtinHandlers.java
@@ -61,7 +61,7 @@ class ObjectIdentifier_builtinHandlers {
         @Override
         public RootOid handle(ManagedObject managedObject) {
             final String identifier = SERVICE_IDENTIFIER;
-            return Oid.Factory.root(managedObject.getSpecification().getSpecId(), identifier);
+            return Oid.Factory.root(managedObject.getSpecification().getLogicalType(), identifier);
         }
 
     }
@@ -87,7 +87,7 @@ class ObjectIdentifier_builtinHandlers {
                 throw _Exceptions.unrecoverable(msg);
             }
             val identifier = entityFacet.identifierFor(spec, pojo);
-            return Oid.Factory.root(spec.getSpecId(), identifier);
+            return Oid.Factory.root(spec.getLogicalType(), identifier);
         }
 
     }
@@ -118,7 +118,7 @@ class ObjectIdentifier_builtinHandlers {
             val spec = managedObject.getSpecification();
             val recreatableObjectFacet = spec.getFacet(ViewModelFacet.class);
             val identifier = recreatableObjectFacet.memento(managedObject.getPojo());
-            return Oid.Factory.root(spec.getSpecId(), identifier);
+            return Oid.Factory.root(spec.getLogicalType(), identifier);
         }
 
     }
@@ -134,7 +134,7 @@ class ObjectIdentifier_builtinHandlers {
         public RootOid handle(ManagedObject managedObject) {
             val spec = managedObject.getSpecification();
             val identifier = UUID.randomUUID().toString();
-            return Oid.Factory.root(spec.getSpecId(), identifier);
+            return Oid.Factory.root(spec.getLogicalType(), identifier);
         }
 
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
index 7ebd562..ba3ce09 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
@@ -33,7 +33,7 @@ import static java.util.Comparator.nullsFirst;
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Value;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.applib.util.Equality;
 import org.apache.isis.applib.util.Hashing;
@@ -42,7 +42,6 @@ import org.apache.isis.applib.util.TitleBuffer;
 import org.apache.isis.applib.util.ToString;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Lists;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 
 import lombok.NonNull;
 import lombok.val;
@@ -73,7 +72,7 @@ implements
 
     public static ApplicationFeatureId fromIdentifier(final @NonNull Identifier identifier) {
         
-        val logicalTypeName = identifier.getTypeIdentifier().getLogicalTypeName();
+        val logicalTypeName = identifier.getLogicalTypeName();
         
         if(identifier.getType().isClass()) {
             return newClass(logicalTypeName); 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
index b94e53e..13826b0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
@@ -30,6 +30,7 @@ import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.commanddto.processor.CommandDtoProcessor;
 import org.apache.isis.applib.services.grid.GridService;
@@ -43,7 +44,6 @@ import org.apache.isis.core.metamodel.facets.members.publish.command.CommandPubl
 import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.MixedIn;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
@@ -70,8 +70,7 @@ public class MetaModelServiceDefault implements MetaModelService {
         if(objectType == null) {
             return null;
         }
-        final ObjectSpecId objectSpecId = ObjectSpecId.of(objectType);
-        final ObjectSpecification objectSpecification = specificationLoader.lookupBySpecIdElseLoad(objectSpecId);
+        final ObjectSpecification objectSpecification = specificationLoader.lookupBySpecIdElseLoad(objectType);
         return objectSpecification != null? objectSpecification.getCorrespondingClass(): null;
     }
 
@@ -221,7 +220,7 @@ public class MetaModelServiceDefault implements MetaModelService {
             return null;
         }
 
-        final ObjectSpecification spec = specificationLoader.lookupBySpecIdElseLoad(objectSpecId);
+        final ObjectSpecification spec = specificationLoader.lookupBySpecIdElseLoad(objectSpecId.asString());
         if(spec == null) {
             return null;
         }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/title/TitlesAndTranslationsValidator.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/title/TitlesAndTranslationsValidator.java
index ccc0c93..52557cd 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/title/TitlesAndTranslationsValidator.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/title/TitlesAndTranslationsValidator.java
@@ -19,7 +19,7 @@
 package org.apache.isis.core.metamodel.services.title;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.title.TitleService;
 import org.apache.isis.commons.internal.base._Blackhole;
@@ -64,7 +64,7 @@ public class TitlesAndTranslationsValidator extends MetaModelValidatorAbstract {
             if(domainService == null) {
                 
                 val deficiencyOrigin = Identifier.classIdentifier(
-                        TypeIdentifier.eager(managedBeanAdapter.getBeanClass(), objectType));
+                        LogicalType.eager(managedBeanAdapter.getBeanClass(), objectType));
                 val facetHolder = specificationLoader.loadSpecification(managedBeanAdapter.getBeanClass());
                 
                 super.onFailure(
@@ -85,7 +85,7 @@ public class TitlesAndTranslationsValidator extends MetaModelValidatorAbstract {
                 e.printStackTrace();
                 
                 val deficiencyOrigin = Identifier.classIdentifier(
-                        TypeIdentifier.eager(managedBeanAdapter.getBeanClass(), objectType));
+                        LogicalType.eager(managedBeanAdapter.getBeanClass(), objectType));
                 val facetHolder = specificationLoader.loadSpecification(managedBeanAdapter.getBeanClass());
 
                 super.onFailure(
@@ -122,7 +122,7 @@ public class TitlesAndTranslationsValidator extends MetaModelValidatorAbstract {
                     } catch (Exception e) {
 
                         val deficiencyOrigin = Identifier.classIdentifier(
-                                TypeIdentifier.eager(correspondingClass, objSpec.getSpecId().asString()));
+                                LogicalType.eager(correspondingClass, objSpec.getSpecId().asString()));
                         val facetHolder = objSpec;
 
                         super.onFailure(
@@ -157,7 +157,7 @@ public class TitlesAndTranslationsValidator extends MetaModelValidatorAbstract {
 
                 val facetHolder = specificationLoader.loadSpecification(MessageRegistry.class);
                 val deficiencyOrigin = Identifier.classIdentifier(
-                        TypeIdentifier.eager(MessageRegistry.class, facetHolder.getSpecId().asString()));
+                        LogicalType.eager(MessageRegistry.class, facetHolder.getSpecId().asString()));
 
                 super.onFailure(
                         facetHolder, 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
index fa37065..8c77c75 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
@@ -34,6 +34,7 @@ import java.util.stream.Stream;
 import javax.annotation.Nullable;
 
 import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.repository.EntityState;
 import org.apache.isis.commons.collections.Can;
@@ -169,7 +170,7 @@ public final class ManagedObjects {
             @Nullable ManagedObject managedObject, 
             @NonNull final String separator) {
         return identify(managedObject)
-                .map(rootOid->rootOid.getObjectSpecId() + separator + rootOid.getIdentifier());
+                .map(rootOid->rootOid.getLogicalTypeName() + separator + rootOid.getIdentifier());
     }
 
     public static String stringifyElseFail(
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
index ca8be8e..cf6f9cc 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
@@ -33,6 +33,8 @@ import javax.annotation.Nullable;
 
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.exceptions.UnrecoverableException;
+import org.apache.isis.applib.id.LogicalType;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.applib.services.metamodel.BeanSort;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.collections._Streams;
@@ -155,7 +157,16 @@ extends
      * <p>
      * The {@link ObjectSpecification} can be retrieved using {@link SpecificationLoader#lookupBySpecIdElseLoad(ObjectSpecId)}}.
      */
-    ObjectSpecId getSpecId();
+    @Deprecated
+    default ObjectSpecId getSpecId() {
+        throw _Exceptions.unsupportedOperation();
+    }
+    
+    LogicalType getLogicalType();
+    
+    default String getLogicalTypeName() {
+        return getLogicalType().getLogicalTypeName();
+    }
 
     /**
      * Returns an (immutable) "full" identifier for this specification.
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecIdToClassResolver.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/LogicalTypeResolver.java
similarity index 87%
rename from core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecIdToClassResolver.java
rename to core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/LogicalTypeResolver.java
index 0582cbc..a36366b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecIdToClassResolver.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/LogicalTypeResolver.java
@@ -20,14 +20,14 @@ package org.apache.isis.core.metamodel.specloader;
 
 import java.util.Optional;
 
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 
 import lombok.NonNull;
 
-interface SpecIdToClassResolver {
+interface LogicalTypeResolver {
 
-    Optional<Class<?>> lookup(@NonNull ObjectSpecId specId);
+    Optional<LogicalType> lookup(@NonNull String logicalTypeName);
     
     void register(@NonNull ObjectSpecification spec);
     
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecIdToClassResolverDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/LogicalTypeResolverDefault.java
similarity index 77%
rename from core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecIdToClassResolverDefault.java
rename to core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/LogicalTypeResolverDefault.java
index e54865a..733806e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecIdToClassResolverDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/LogicalTypeResolverDefault.java
@@ -22,31 +22,31 @@ package org.apache.isis.core.metamodel.specloader;
 import java.util.Map;
 import java.util.Optional;
 
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 
 import lombok.NonNull;
 
-class SpecIdToClassResolverDefault implements SpecIdToClassResolver {
+class LogicalTypeResolverDefault implements LogicalTypeResolver {
 
-    private final Map<ObjectSpecId, Class<?>> classBySpecId = _Maps.newConcurrentHashMap();
+    private final Map<String, LogicalType> logicalTypeByName = _Maps.newConcurrentHashMap();
 
     @Override
     public void clear() {
-        classBySpecId.clear();
+        logicalTypeByName.clear();
     }
 
     @Override
-    public Optional<Class<?>> lookup(final @NonNull ObjectSpecId specId) {
-        return Optional.ofNullable(classBySpecId.get(specId));
+    public Optional<LogicalType> lookup(final @NonNull String logicalTypeName) {
+        return Optional.ofNullable(logicalTypeByName.get(logicalTypeName));
     }
     
     @Override
     public void register(final @NonNull ObjectSpecification spec) {
         if(hasUsableSpecId(spec)) {
-            classBySpecId.put(spec.getSpecId(), spec.getCorrespondingClass());
+            logicalTypeByName.put(spec.getLogicalTypeName(), spec.getLogicalType());
         }
     }
     
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
index cdb6444..5bdab4f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
@@ -22,10 +22,11 @@ import java.util.function.Consumer;
 
 import javax.annotation.Nullable;
 
+import org.apache.isis.applib.id.LogicalType;
+import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutor;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.specimpl.IntrospectionState;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidator;
@@ -100,9 +101,9 @@ public interface SpecificationLoader {
      * @param domainTypes
      * @return true if a specification could be loaded for all types, false otherwise
      */
-    boolean loadSpecifications(final Class<?>... domainTypes);
+    boolean loadSpecifications(Class<?>... domainTypes);
 
-    Class<?> lookupType(ObjectSpecId objectSpecId);
+    LogicalType lookupLogicalType(@Nullable String logicalTypeName);
 
     /**
      * queue {@code objectSpec} for later validation
@@ -113,34 +114,56 @@ public interface SpecificationLoader {
     // -- SHORTCUTS
 
     @Nullable
-    default ObjectSpecification loadSpecification(@Nullable Class<?> domainType) {
+    default ObjectSpecification loadSpecification(
+            final @Nullable Class<?> domainType) {
         return loadSpecification(domainType, IntrospectionState.TYPE_INTROSPECTED);
     }
 
     @Nullable
-    default ObjectSpecification loadSpecification(@Nullable ObjectSpecId objectSpecId) {
-        return loadSpecification(objectSpecId, IntrospectionState.TYPE_INTROSPECTED);
+    default ObjectSpecification loadSpecification(
+            final @Nullable String logicalTypeName) {
+        return loadSpecification(logicalTypeName, IntrospectionState.TYPE_INTROSPECTED);
     }
     
     @Nullable
     default ObjectSpecification loadSpecification(
-            @Nullable ObjectSpecId objectSpecId, 
-            @NonNull IntrospectionState introspectionState) {
+            final @Nullable LogicalType logicalType) {
+        return loadSpecification(logicalType.getCorrespondingClass(), IntrospectionState.TYPE_INTROSPECTED);
+    }
+    
+    @Nullable
+    default ObjectSpecification loadSpecification(
+            final @Nullable Bookmark bookmark) {
+        return loadSpecification(bookmark.getLogicalTypeName(), IntrospectionState.TYPE_INTROSPECTED);
+    }
+    
+    @Nullable
+    default ObjectSpecification loadSpecification(
+            final @Nullable String logicalTypeName, 
+            final @NonNull  IntrospectionState introspectionState) {
 
-        if(objectSpecId==null) {
+        if(logicalTypeName==null) {
             return null;
         }
-        val type = lookupType(objectSpecId);
-        return loadSpecification(type, introspectionState);
+        val logicalType = lookupLogicalType(logicalTypeName);
+        return loadSpecification(logicalType.getCorrespondingClass(), introspectionState);
     }
 
     /**
      * Lookup a specification that has bean loaded before.
      * @param objectSpecId
+     * //TODO[2533] rename
      */
     @Nullable
-    default ObjectSpecification lookupBySpecIdElseLoad(@Nullable ObjectSpecId objectSpecId) {
-        return loadSpecification(objectSpecId, IntrospectionState.TYPE_AND_MEMBERS_INTROSPECTED);
+    default ObjectSpecification lookupBySpecIdElseLoad(
+            final @Nullable String logicalTypeName) {
+        return loadSpecification(logicalTypeName, IntrospectionState.TYPE_AND_MEMBERS_INTROSPECTED);
+    }
+    
+    @Nullable
+    default ObjectSpecification lookupBySpecIdElseLoad(
+            final @Nullable LogicalType logicalType) {
+        return loadSpecification(logicalType.getCorrespondingClass(), IntrospectionState.TYPE_AND_MEMBERS_INTROSPECTED);
     }
     
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
index e99d481..81d201e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
@@ -38,6 +38,7 @@ import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.metamodel.BeanSort;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
 import org.apache.isis.commons.collections.Can;
@@ -65,7 +66,6 @@ import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutor
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutorDefault;
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutorForCollections;
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutorRegistry;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.facetprocessor.FacetProcessor;
 import org.apache.isis.core.metamodel.specloader.postprocessor.PostProcessor;
@@ -121,7 +121,7 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
     private FacetProcessor facetProcessor;
 
     private final SpecificationCache<ObjectSpecification> cache = new SpecificationCacheDefault<>();
-    private final SpecIdToClassResolver specIdToClassResolver = new SpecIdToClassResolverDefault();
+    private final LogicalTypeResolver logicalTypeResolver = new LogicalTypeResolverDefault();
 
     /**
      * We only ever mark the meta-model as fully introspected if in {@link #isFullIntrospect() full} 
@@ -318,7 +318,7 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
 
     @Override
     public void disposeMetaModel() {
-        specIdToClassResolver.clear();
+        logicalTypeResolver.clear();
         cache.clear();
         validationResult.clear();
         log.info("Metamodel disposed.");
@@ -429,17 +429,19 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
     }
 
     @Override
-    public Class<?> lookupType(final @NonNull ObjectSpecId objectSpecId) {
-        Class<?> cls = specIdToClassResolver.lookup(objectSpecId)
+    public LogicalType lookupLogicalType(final @NonNull String logicalTypeName) {
+        val logicalType = logicalTypeResolver.lookup(logicalTypeName)
                 .orElse(null);
-        if(cls!=null) {
-            return cls;
+        if(logicalType!=null) {
+            return logicalType;
         }
         
-        // falling back assuming the specId equals the fqn of the corresponding class
-        // which might not always be true, hence the warning
-        //TODO desired behavior could be made a config option, eg. to throw an exception here instead
-        cls = ClassUtil.forNameElseNull(objectSpecId.asString());
+        //TODO[2533] if the logicalTypeName is not available and instead a fqcn was passed in, that should also be supported 
+        
+        // falling back assuming the logicalTypeName equals the fqn of the corresponding class
+        // which might not always be true, 
+        
+        val cls = ClassUtil.forNameElseNull(logicalTypeName);
         if(cls!=null) {
 
 //TODO yet it seems we rely on this kind of fallback from several code paths, so lets not emit any warnings yet ...              
@@ -448,15 +450,15 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
 //                    + "discovered by Spring during bootstrapping of this application.", 
 //                    objectSpecId.getSpecId(),
 //                    cls.getName());
-            return cls;
+            return LogicalType.fqcn(cls);
         }
         
         // immediately fail to not cause any NPEs further down the path
         throw _Exceptions.unrecoverableFormatted(
-                "Lookup for ObjectSpecId '%s' failed, also found no matching fully qualified "
+                "Lookup of logical-type-name '%s' failed, also found no matching fully qualified "
                 + "class name to use instead. This indicates, that the class we are not finding here"
                 + " is not discovered by Spring during bootstrapping of this application.",
-                objectSpecId.asString());
+                logicalTypeName);
     }
     
     // -- VALIDATION STUFF
@@ -517,7 +519,7 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
         
         final ObjectSpecification spec = cache.computeIfAbsent(substitutedType, __->{
             val newSpec = createSpecification(substitutedType, beanClassifier.apply(type));
-            specIdToClassResolver.register(newSpec);
+            logicalTypeResolver.register(newSpec);
             return newSpec;
         });
 
@@ -628,5 +630,4 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
         }
     }
 
-
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
index a1ebf20..29ee7ef 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
@@ -19,7 +19,7 @@
 package org.apache.isis.core.metamodel.specloader.specimpl;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.collections.CanVector;
 import org.apache.isis.commons.internal.assertions._Assert;
@@ -91,7 +91,7 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
         final Identifier mixinIdentifier = mixinAction.getFacetedMethod().getIdentifier();
         val memberParameterClassNames = mixinIdentifier.getMemberParameterClassNames();
         identifier = Identifier.actionIdentifier(
-                TypeIdentifier.eager(
+                LogicalType.eager(
                         getOnType().getCorrespondingClass(),
                         getOnType().getSpecId().asString()),
                 getId(), 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
index 9018b26..96240ac 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
@@ -33,7 +33,8 @@ import java.util.stream.Stream;
 import javax.enterprise.inject.Vetoed;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.applib.services.metamodel.BeanSort;
 import org.apache.isis.commons.collections.ImmutableEnumSet;
 import org.apache.isis.commons.internal.base._Lazy;
@@ -74,7 +75,6 @@ import org.apache.isis.core.metamodel.interactions.ObjectTitleContext;
 import org.apache.isis.core.metamodel.interactions.ObjectValidityContext;
 import org.apache.isis.core.metamodel.spec.ActionType;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.MixedIn;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
@@ -214,7 +214,7 @@ implements ObjectSpecification {
         this.isAbstract = ClassExtensions.isAbstract(introspectedClass);
 
         this.identifier = Identifier.classIdentifier(
-                TypeIdentifier.lazy(
+                LogicalType.lazy(
                         introspectedClass,
                         ()->specIdLazy.get().asString()));
 
@@ -228,10 +228,17 @@ implements ObjectSpecification {
         return FeatureType.OBJECT;
     }
 
-    @Override
+    @Override //TODO[2553] 
+    @Deprecated //use getLogicalTypeName() instead
     public ObjectSpecId getSpecId() {
         return specIdLazy.get();
     }
+    
+    @Override
+    public LogicalType getLogicalType() {
+        //TODO[2553] add memoization
+        return LogicalType.eager(correspondingClass, specIdLazy.get().asString());
+    }
         
     private ObjectSpecId lookupSpecId() {
         val objectSpecIdFacet = getFacet(ObjectSpecIdFacet.class);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
index 8debfdb..167fb51 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
@@ -20,7 +20,7 @@ package org.apache.isis.core.metamodel.specloader.specimpl;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -129,7 +129,7 @@ public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault imp
         val memberParameterNames = mixinIdentifier.getMemberParameterClassNames();
 
         identifier = Identifier.actionIdentifier(
-                TypeIdentifier.eager(
+                LogicalType.eager(
                         mixeeSpec.getCorrespondingClass(), 
                         mixeeSpec.getSpecId().asString()), 
                 getId(), 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
index 537379c..c487943 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
@@ -20,7 +20,7 @@ package org.apache.isis.core.metamodel.specloader.specimpl;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -109,7 +109,7 @@ public class OneToOneAssociationMixedIn extends OneToOneAssociationDefault imple
         val memberParameterClassNames = mixinIdentifier.getMemberParameterClassNames();
 
         identifier = Identifier.actionIdentifier(
-                TypeIdentifier.eager(
+                LogicalType.eager(
                         mixeeSpec.getCorrespondingClass(), 
                         mixeeSpec.getSpecId().asString()),
                 getId(), 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
index da67aa2..07dacf7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
@@ -27,6 +27,7 @@ import java.util.function.BiConsumer;
 import java.util.stream.Stream;
 
 import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.metamodel.BeanSort;
 import org.apache.isis.commons.collections.ImmutableEnumSet;
 import org.apache.isis.commons.internal.base._Lazy;
@@ -375,6 +376,5 @@ implements FacetHolder {
                 .map(typeOfFacet -> ElementSpecificationProvider.of(typeOfFacet).getElementType());
     }
 
-    // --
 
 }
diff --git a/security/shiro/src/test/java/org/apache/isis/security/shiro/TypeIdentifierTestFactory.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/LogicalTypeTestFactory.java
similarity index 65%
copy from security/shiro/src/test/java/org/apache/isis/security/shiro/TypeIdentifierTestFactory.java
copy to core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/LogicalTypeTestFactory.java
index 7fa0571..cac40e7 100644
--- a/security/shiro/src/test/java/org/apache/isis/security/shiro/TypeIdentifierTestFactory.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/LogicalTypeTestFactory.java
@@ -16,21 +16,24 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.security.shiro;
+package org.apache.isis.core.metamodel.adapter.oid;
 
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 
-final class TypeIdentifierTestFactory {
-
-    static TypeIdentifier customer() {
-        return TypeIdentifier.fqcn(Customer.class);
+public class LogicalTypeTestFactory {
+    
+    public static LogicalType cus() {
+        return LogicalType.lazy(Customer.class, ()->"CUS");
     }
     
-    static TypeIdentifier order() {
-        return TypeIdentifier.fqcn(Order.class);
+    public static LogicalType cux() {
+        return LogicalType.lazy(Customer.class, ()->"CUX");
     }
     
+    public static LogicalType ord() {
+        return LogicalType.lazy(Order.class, ()->"ORD");
+    }
 }
 
 final class Customer {}
-final class Order {};
+final class Order {}
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_marshall.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_marshall.java
index 6b5e75f..abac218 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_marshall.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_marshall.java
@@ -24,8 +24,6 @@ import org.junit.Test;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
-
 public class OidMarshallerTest_marshall {
 
     private Oid_Marshaller oidMarshaller;
@@ -37,7 +35,7 @@ public class OidMarshallerTest_marshall {
 
     @Test
     public void rootOid() {
-        final String marshal = oidMarshaller.marshal(Oid.Factory.root(ObjectSpecId.of("CUS"),  "123"));
+        final String marshal = oidMarshaller.marshal(Oid.Factory.root(LogicalTypeTestFactory.cus(),  "123"));
         assertThat(marshal, equalTo("CUS:123"));
     }
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_roundtripping.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_roundtripping.java
index e65f99a..344dcd3 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_roundtripping.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_roundtripping.java
@@ -24,13 +24,11 @@ import org.junit.Test;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
-
 public class OidMarshallerTest_roundtripping {
 
     @Test
     public void rootOid() {
-        RootOid oid = Oid.Factory.root(ObjectSpecId.of("CUS"), "123");
+        RootOid oid = Oid.Factory.root(LogicalTypeTestFactory.cus(), "123");
 
         final String enString = oid.enString();
         final RootOid deString = RootOid.deString(enString);
@@ -39,7 +37,7 @@ public class OidMarshallerTest_roundtripping {
     
     @Test
     public void rootOid_withLegacyVersionIgnored() {
-        RootOid oid = Oid.Factory.root(ObjectSpecId.of("CUS"), "123");
+        RootOid oid = Oid.Factory.root(LogicalTypeTestFactory.cus(), "123");
 
         final String enString = oid.enString();
         final RootOid deString = RootOid.deString(enString + "^" + 90807L);
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_unmarshal.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_unmarshal.java
index 205e9ae..e676f86 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_unmarshal.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_unmarshal.java
@@ -25,8 +25,6 @@ import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
-
 /**
  * <dt>CUS:123</dt>
  * <dd>persistent root</dd>
@@ -69,7 +67,7 @@ public class OidMarshallerTest_unmarshal {
         final String oidStr = "CUS:123";
 
         final RootOid rootOid = oidMarshaller.unmarshal(oidStr, RootOid.class);
-        assertThat(rootOid.getObjectSpecId(), is(ObjectSpecId.of("CUS")));
+        assertThat(rootOid.getLogicalTypeName(), is("CUS"));
         assertThat(rootOid.getIdentifier(), is("123"));
 
         final Oid oid = oidMarshaller.unmarshal(oidStr, Oid.class);
@@ -81,7 +79,7 @@ public class OidMarshallerTest_unmarshal {
         final String oidStr = "com.planchase.ClassName:8";
 
         final RootOid rootOid = oidMarshaller.unmarshal(oidStr, RootOid.class);
-        assertThat(rootOid.getObjectSpecId(), is(ObjectSpecId.of("com.planchase.ClassName")));
+        assertThat(rootOid.getLogicalTypeName(), is("com.planchase.ClassName"));
         assertThat(rootOid.getIdentifier(), is("8"));
 
         final Oid oid = oidMarshaller.unmarshal(oidStr, Oid.class);
@@ -102,7 +100,7 @@ public class OidMarshallerTest_unmarshal {
         final String oidStr = "!CUS:123";
 
         final RootOid rootOid = oidMarshaller.unmarshal(oidStr, RootOid.class);
-        assertThat(rootOid.getObjectSpecId(), is(ObjectSpecId.of("CUS")));
+        assertThat(rootOid.getLogicalTypeName(), is("CUS"));
         assertThat(rootOid.getIdentifier(), is("123"));
 
         final Oid oid = oidMarshaller.unmarshal(oidStr, Oid.class);
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidVersionTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidVersionTest.java
index acfa09a..eff870b 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidVersionTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidVersionTest.java
@@ -25,35 +25,35 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.applib.id.LogicalType;
 
 public class OidVersionTest  {
 
-    private ObjectSpecId cusObjectSpecId = ObjectSpecId.of("CUS");
-    private ObjectSpecId ordObjectSpecId = ObjectSpecId.of("ORD");
+    private LogicalType cus = LogicalTypeTestFactory.cus();
+    private LogicalType ord = LogicalTypeTestFactory.ord();
 
     private RootOid oid1, oid2;
 
     @Test
     public void whenEquivalent() throws Exception {
-        oid1 = Oid.Factory.root(cusObjectSpecId, "123");
-        oid2 = Oid.Factory.root(cusObjectSpecId, "123");
+        oid1 = Oid.Factory.root(cus, "123");
+        oid2 = Oid.Factory.root(cus, "123");
 
         assertThat(oid1, is(equalTo(oid2)));
     }
 
     @Test
     public void whenNotEquivalentById() throws Exception {
-        oid1 = Oid.Factory.root(cusObjectSpecId, "123");
-        oid2 = Oid.Factory.root(cusObjectSpecId, "124");
+        oid1 = Oid.Factory.root(cus, "123");
+        oid2 = Oid.Factory.root(cus, "124");
 
         assertThat(oid1, is(not(equalTo(oid2))));
     }
 
     @Test
     public void whenNotEquivalentByObjectSpecId() throws Exception {
-        oid1 = Oid.Factory.root(cusObjectSpecId, "123");
-        oid2 = Oid.Factory.root(ordObjectSpecId, "123");
+        oid1 = Oid.Factory.root(cus, "123");
+        oid2 = Oid.Factory.root(ord, "123");
 
         assertThat(oid1, is(not(equalTo(oid2))));
     }
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/RootOidDefaultTest_valueSemantics_whenPersistent.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/RootOidDefaultTest_valueSemantics_whenPersistent.java
index 20c39d5..b8a2d09 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/RootOidDefaultTest_valueSemantics_whenPersistent.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/RootOidDefaultTest_valueSemantics_whenPersistent.java
@@ -22,24 +22,24 @@ import java.util.Arrays;
 import java.util.List;
 
 import org.apache.isis.core.internaltestsupport.contract.ValueTypeContractTestAbstract;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 
-public class RootOidDefaultTest_valueSemantics_whenPersistent extends ValueTypeContractTestAbstract<RootOid> {
+public class RootOidDefaultTest_valueSemantics_whenPersistent 
+extends ValueTypeContractTestAbstract<RootOid> {
 
     @Override
     protected List<RootOid> getObjectsWithSameValue() {
         return Arrays.asList(
-                Oid.Factory.root(ObjectSpecId.of("CUS"), "123"),
-                Oid.Factory.root(ObjectSpecId.of("CUS"), "123"),
-                Oid.Factory.root(ObjectSpecId.of("CUS"), "123"));
+                Oid.Factory.root(LogicalTypeTestFactory.cus(), "123"),
+                Oid.Factory.root(LogicalTypeTestFactory.cus(), "123"),
+                Oid.Factory.root(LogicalTypeTestFactory.cus(), "123"));
     }
 
     @Override
     protected List<RootOid> getObjectsWithDifferentValue() {
         return Arrays.asList(
                 //Oid.Factory.of(ObjectSpecId.of("CUS"), "123"),
-                Oid.Factory.root(ObjectSpecId.of("CUS"), "124"),
-                Oid.Factory.root(ObjectSpecId.of("CUX"), "123"));
+                Oid.Factory.root(LogicalTypeTestFactory.cus(), "124"),
+                Oid.Factory.root(LogicalTypeTestFactory.cux(), "123"));
     }
 
 }
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/RootOidTest_create.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/RootOidTest_create.java
index 810f784..6c5ac96 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/RootOidTest_create.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/RootOidTest_create.java
@@ -23,16 +23,15 @@ import org.junit.Test;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import lombok.val;
 
 public class RootOidTest_create {
 
-
     @Test
     public void create() throws Exception {
-        ObjectSpecId objectSpecId = ObjectSpecId.of("CUS");
-        RootOid oid = Oid.Factory.root(objectSpecId, "123");
-        assertThat(oid.getObjectSpecId(), is(objectSpecId));
+        val logicalType = LogicalTypeTestFactory.cus();
+        RootOid oid = Oid.Factory.root(logicalType, "123");
+        assertThat(oid.getLogicalTypeName(), is(logicalType.getLogicalTypeName()));
         assertThat(oid.getIdentifier(), is("123"));
     }
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facetapi/FeatureTypeTest_identifierFor.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facetapi/FeatureTypeTest_identifierFor.java
index 54e329a..1da5ef4 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facetapi/FeatureTypeTest_identifierFor.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facetapi/FeatureTypeTest_identifierFor.java
@@ -28,7 +28,7 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 
 public class FeatureTypeTest_identifierFor {
 
@@ -58,7 +58,7 @@ public class FeatureTypeTest_identifierFor {
     public void property_whenMethodNameIs_XYyyZzz() throws Exception {
         final Method method = SomeDomainClass.class.getMethod("getABigDecimal");
         final Identifier identifierFor = FeatureType.PROPERTY.identifierFor(
-                TypeIdentifier.fqcn(SomeDomainClass.class), method);
+                LogicalType.fqcn(SomeDomainClass.class), method);
         assertThat(identifierFor.getMemberName(), is("ABigDecimal")); // very
         // odd
         // compared
@@ -81,7 +81,7 @@ public class FeatureTypeTest_identifierFor {
     public void property_whenMethodNameIs_XxxxYyyZzz() throws Exception {
         final Method method = SomeDomainClass.class.getMethod("getAnotherBigDecimal");
         final Identifier identifierFor = FeatureType.PROPERTY.identifierFor(
-                TypeIdentifier.fqcn(SomeDomainClass.class), method);
+                LogicalType.fqcn(SomeDomainClass.class), method);
         assertThat(identifierFor.getMemberName(), is("anotherBigDecimal"));
     }
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/AbstractFacetFactoryJUnit4TestCase.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/AbstractFacetFactoryJUnit4TestCase.java
index d927beb..2af781f 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/AbstractFacetFactoryJUnit4TestCase.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/AbstractFacetFactoryJUnit4TestCase.java
@@ -29,7 +29,7 @@ import org.junit.Before;
 import org.junit.Rule;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.inject.ServiceInjector;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
@@ -118,7 +118,7 @@ public abstract class AbstractFacetFactoryJUnit4TestCase {
         }});
 
         facetHolder = new AbstractFacetFactoryTest.IdentifiedHolderImpl(
-                Identifier.propertyOrCollectionIdentifier(TypeIdentifier.fqcn(Customer.class), "firstName"));
+                Identifier.propertyOrCollectionIdentifier(LogicalType.fqcn(Customer.class), "firstName"));
         facetedMethod = FacetedMethod.createForProperty(AbstractFacetFactoryTest.Customer.class, "firstName");
         facetedMethodParameter = new FacetedMethodParameter(FeatureType.ACTION_PARAMETER_SCALAR, facetedMethod.getOwningType(), facetedMethod.getMethod(), String.class);
         
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/AbstractFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/AbstractFacetFactoryTest.java
index 23f9db2..b5248ed 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/AbstractFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/AbstractFacetFactoryTest.java
@@ -26,7 +26,7 @@ import org.jmock.Expectations;
 import org.junit.Rule;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.collections.ImmutableEnumSet;
 import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
@@ -94,7 +94,7 @@ public abstract class AbstractFacetFactoryTest extends TestCase {
         // PRODUCTION
 
         facetHolder = new IdentifiedHolderImpl(
-                Identifier.propertyOrCollectionIdentifier(TypeIdentifier.fqcn(Customer.class), "firstName"));
+                Identifier.propertyOrCollectionIdentifier(LogicalType.fqcn(Customer.class), "firstName"));
         facetedMethod = FacetedMethod.createForProperty(Customer.class, "firstName");
         facetedMethodParameter = new FacetedMethodParameter(
                 FeatureType.ACTION_PARAMETER_SCALAR, facetedMethod.getOwningType(), facetedMethod.getMethod(), String.class
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newActionInteractionEvent.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newActionInteractionEvent.java
index ac8c5bc..1c0e981 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newActionInteractionEvent.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newActionInteractionEvent.java
@@ -28,7 +28,7 @@ import static org.junit.Assert.assertSame;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.events.domain.ActionDomainEvent;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 
 import static junit.framework.Assert.assertEquals;
 
@@ -43,7 +43,7 @@ public class DomainEventHelperTest_newActionInteractionEvent {
     @Test
     public void defaultEventType() throws Exception {
         final SomeDomainObject sdo = new SomeDomainObject();
-        final Identifier identifier = Identifier.actionIdentifier(TypeIdentifier.fqcn(SomeDomainObject.class), "foo", new Class[]{int.class, String.class});
+        final Identifier identifier = Identifier.actionIdentifier(LogicalType.fqcn(SomeDomainObject.class), "foo", new Class[]{int.class, String.class});
 
         Utils.domainEventHelper();
         final ActionDomainEvent<Object> ev = DomainEventHelper.newActionDomainEvent(
@@ -58,7 +58,7 @@ public class DomainEventHelperTest_newActionInteractionEvent {
     @Test
     public void actionInvokedEventDefaultEventType() throws Exception {
         final SomeDomainObject sdo = new SomeDomainObject();
-        final Identifier identifier = Identifier.actionIdentifier(TypeIdentifier.fqcn(SomeDomainObject.class), "foo", new Class[]{int.class, String.class});
+        final Identifier identifier = Identifier.actionIdentifier(LogicalType.fqcn(SomeDomainObject.class), "foo", new Class[]{int.class, String.class});
 
         Utils.domainEventHelper();
         final ActionDomainEvent<Object> ev = DomainEventHelper.newActionDomainEvent(
@@ -73,7 +73,7 @@ public class DomainEventHelperTest_newActionInteractionEvent {
     @Test
     public void customEventType() throws Exception {
         final SomeDomainObject sdo = new SomeDomainObject();
-        final Identifier identifier = Identifier.actionIdentifier(TypeIdentifier.fqcn(SomeDomainObject.class), "foo", new Class[]{int.class, String.class});
+        final Identifier identifier = Identifier.actionIdentifier(LogicalType.fqcn(SomeDomainObject.class), "foo", new Class[]{int.class, String.class});
 
         Utils.domainEventHelper();
         final ActionDomainEvent<SomeDomainObject> ev = DomainEventHelper.newActionDomainEvent(
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newCollectionDomainEvent_forAdd.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newCollectionDomainEvent_forAdd.java
index 40e08fc..d586a41 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newCollectionDomainEvent_forAdd.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newCollectionDomainEvent_forAdd.java
@@ -29,7 +29,7 @@ import static org.junit.Assert.assertSame;
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.events.domain.AbstractDomainEvent;
 import org.apache.isis.applib.events.domain.CollectionDomainEvent;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 
 public class DomainEventHelperTest_newCollectionDomainEvent_forAdd {
 
@@ -45,7 +45,7 @@ public class DomainEventHelperTest_newCollectionDomainEvent_forAdd {
         final SomeDomainObject sdo = new SomeDomainObject();
         final SomeReferencedObject other = new SomeReferencedObject();
         final Identifier identifier = Identifier.propertyOrCollectionIdentifier(
-                TypeIdentifier.fqcn(SomeDomainObject.class), "references");
+                LogicalType.fqcn(SomeDomainObject.class), "references");
 
         final CollectionDomainEvent<Object, Object> ev = Utils.domainEventHelper().newCollectionDomainEvent(
                 CollectionDomainEvent.Default.class, null, identifier, sdo, CollectionDomainEvent.Of.ADD_TO, other);
@@ -60,7 +60,7 @@ public class DomainEventHelperTest_newCollectionDomainEvent_forAdd {
         final SomeDomainObject sdo = new SomeDomainObject();
         final SomeReferencedObject other = new SomeReferencedObject();
         final Identifier identifier = Identifier.propertyOrCollectionIdentifier(
-                TypeIdentifier.fqcn(SomeDomainObject.class), "references");
+                LogicalType.fqcn(SomeDomainObject.class), "references");
 
         final CollectionDomainEvent<Object, Object> ev = Utils.domainEventHelper().newCollectionDomainEvent(
                 CollectionDomainEvent.Default.class, AbstractDomainEvent.Phase.EXECUTED, identifier, sdo, CollectionDomainEvent.Of.ADD_TO, other);
@@ -75,7 +75,7 @@ public class DomainEventHelperTest_newCollectionDomainEvent_forAdd {
         final SomeDomainObject sdo = new SomeDomainObject();
         final SomeReferencedObject other = new SomeReferencedObject();
         final Identifier identifier = Identifier.propertyOrCollectionIdentifier(
-                TypeIdentifier.fqcn(SomeDomainObject.class), "references");
+                LogicalType.fqcn(SomeDomainObject.class), "references");
 
         final CollectionDomainEvent<SomeDomainObject, SomeReferencedObject> ev = Utils.domainEventHelper().newCollectionDomainEvent(
                 SomeDomainObjectCollectionDomainEvent.class, AbstractDomainEvent.Phase.EXECUTED, identifier, sdo, CollectionDomainEvent.Of.ADD_TO, other);
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newCollectionDomainEvent_forRemove.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newCollectionDomainEvent_forRemove.java
index 78b74fe..b07c9e2 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newCollectionDomainEvent_forRemove.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newCollectionDomainEvent_forRemove.java
@@ -29,7 +29,7 @@ import static org.junit.Assert.assertSame;
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.events.domain.AbstractDomainEvent;
 import org.apache.isis.applib.events.domain.CollectionDomainEvent;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 
 public class DomainEventHelperTest_newCollectionDomainEvent_forRemove {
 
@@ -45,7 +45,7 @@ public class DomainEventHelperTest_newCollectionDomainEvent_forRemove {
         SomeDomainObject sdo = new SomeDomainObject();
         SomeReferencedObject other = new SomeReferencedObject();
         Identifier identifier = Identifier.propertyOrCollectionIdentifier(
-                TypeIdentifier.fqcn(SomeDomainObject.class), "references");
+                LogicalType.fqcn(SomeDomainObject.class), "references");
 
         final CollectionDomainEvent<Object, Object> ev = Utils.domainEventHelper().newCollectionDomainEvent(
                 CollectionDomainEvent.Default.class, AbstractDomainEvent.Phase.EXECUTED, identifier, sdo, CollectionDomainEvent.Of.REMOVE_FROM, other);
@@ -60,7 +60,7 @@ public class DomainEventHelperTest_newCollectionDomainEvent_forRemove {
         SomeDomainObject sdo = new SomeDomainObject();
         SomeReferencedObject other = new SomeReferencedObject();
         Identifier identifier = Identifier.propertyOrCollectionIdentifier(
-                TypeIdentifier.fqcn(SomeDomainObject.class), "references");
+                LogicalType.fqcn(SomeDomainObject.class), "references");
 
         final CollectionDomainEvent<Object, Object> ev = Utils.domainEventHelper().newCollectionDomainEvent(
                 CollectionDomainEvent.Default.class, AbstractDomainEvent.Phase.EXECUTED, identifier, sdo, CollectionDomainEvent.Of.REMOVE_FROM, other);
@@ -75,7 +75,7 @@ public class DomainEventHelperTest_newCollectionDomainEvent_forRemove {
         SomeDomainObject sdo = new SomeDomainObject();
         SomeReferencedObject other = new SomeReferencedObject();
         Identifier identifier = Identifier.propertyOrCollectionIdentifier(
-                TypeIdentifier.fqcn(SomeDomainObject.class), "references");
+                LogicalType.fqcn(SomeDomainObject.class), "references");
 
         final CollectionDomainEvent<SomeDomainObject, SomeReferencedObject> ev = Utils.domainEventHelper().newCollectionDomainEvent(
                 SomeDomainObjectCollectionRemovedFromDomainEvent.class, AbstractDomainEvent.Phase.EXECUTED, identifier, sdo, CollectionDomainEvent.Of.REMOVE_FROM, other);
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newPropertyDomainEvent_forClear.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newPropertyDomainEvent_forClear.java
index fb0b62c..258d5a2 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newPropertyDomainEvent_forClear.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newPropertyDomainEvent_forClear.java
@@ -29,7 +29,7 @@ import static org.junit.Assert.assertSame;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.events.domain.PropertyDomainEvent;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 
 import static junit.framework.Assert.assertEquals;
 
@@ -45,7 +45,7 @@ public class DomainEventHelperTest_newPropertyDomainEvent_forClear {
 
         SomeDomainObject sdo = new SomeDomainObject();
         Identifier identifier = Identifier.propertyOrCollectionIdentifier(
-                TypeIdentifier.fqcn(SomeDomainObject.class), "someDateProperty");
+                LogicalType.fqcn(SomeDomainObject.class), "someDateProperty");
         LocalDate oldValue = LocalDate.of(2013,4,1);
         LocalDate newValue = null;
 
@@ -64,7 +64,7 @@ public class DomainEventHelperTest_newPropertyDomainEvent_forClear {
 
         SomeDomainObject sdo = new SomeDomainObject();
         Identifier identifier = Identifier.propertyOrCollectionIdentifier(
-                TypeIdentifier.fqcn(SomeDomainObject.class), "someDateProperty");
+                LogicalType.fqcn(SomeDomainObject.class), "someDateProperty");
         LocalDate oldValue = LocalDate.of(2013,4,1);
         LocalDate newValue = null;
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newPropertyDomainEvent_forModify.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newPropertyDomainEvent_forModify.java
index 35666b9..8c130e5 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newPropertyDomainEvent_forModify.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/DomainEventHelperTest_newPropertyDomainEvent_forModify.java
@@ -27,7 +27,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.events.domain.PropertyDomainEvent;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 
 public class DomainEventHelperTest_newPropertyDomainEvent_forModify {
 
@@ -41,7 +41,7 @@ public class DomainEventHelperTest_newPropertyDomainEvent_forModify {
 
         SomeDomainObject sdo = new SomeDomainObject();
         Identifier identifier = Identifier.propertyOrCollectionIdentifier(
-                TypeIdentifier.fqcn(SomeDomainObject.class), "someDateProperty");
+                LogicalType.fqcn(SomeDomainObject.class), "someDateProperty");
         LocalDate oldValue = LocalDate.of(2013,4,1);
         LocalDate newValue = LocalDate.of(2013,5,2);
 
@@ -60,7 +60,7 @@ public class DomainEventHelperTest_newPropertyDomainEvent_forModify {
 
         SomeDomainObject sdo = new SomeDomainObject();
         Identifier identifier = Identifier.propertyOrCollectionIdentifier(
-                TypeIdentifier.fqcn(SomeDomainObject.class), "someDateProperty");
+                LogicalType.fqcn(SomeDomainObject.class), "someDateProperty");
         LocalDate oldValue = LocalDate.of(2013,4,1);
         LocalDate newValue = LocalDate.of(2013,5,2);
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
index e336e5f..a2246a7 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
@@ -34,6 +34,7 @@ import static org.junit.Assert.assertFalse;
 
 import org.apache.isis.applib.annotation.Bounding;
 import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.commons.having.HasUniqueId;
 import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.core.config.metamodel.facets.EditingObjectsConfiguration;
@@ -58,7 +59,6 @@ import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFac
 import org.apache.isis.core.metamodel.facets.object.publish.entitychange.EntityChangePublishingFacet;
 import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
 import org.apache.isis.core.metamodel.facets.objectvalue.choices.ChoicesFacet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 
 import lombok.val;
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectTypeAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectTypeAnnotationFacetFactoryTest.java
index 1aa4707..8c6a3b6 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectTypeAnnotationFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectTypeAnnotationFacetFactoryTest.java
@@ -28,11 +28,11 @@ import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryJUnit4TestCase;
 import org.apache.isis.core.metamodel.facets.ObjectSpecIdFacetFactory.ProcessObjectSpecIdContext;
 import org.apache.isis.core.metamodel.facets.object.domainobject.objectspecid.ObjectSpecIdFacetForDomainObjectAnnotation;
 import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 
 public class ObjectTypeAnnotationFacetFactoryTest extends AbstractFacetFactoryJUnit4TestCase {
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinIntendedAs.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinIntendedAs.java
index 5fe3636..174e3f2 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinIntendedAs.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinIntendedAs.java
@@ -26,7 +26,7 @@ import org.mockito.Mockito;
 import static org.mockito.Mockito.when;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.i18n.Mode;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.inject.ServiceInjector;
@@ -91,7 +91,7 @@ abstract class MixinIntendedAs {
     protected FacetHolder runTypeContextOn(Class<?> type) {
 
         val facetHolder = new AbstractFacetFactoryTest.IdentifiedHolderImpl(
-              Identifier.classIdentifier(TypeIdentifier.fqcn(type)));
+              Identifier.classIdentifier(LogicalType.fqcn(type)));
         facetHolder.setMetaModelContext(metaModelContext);
 
         val processClassContext =
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetDerivedFromClassNameFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetDerivedFromClassNameFactoryTest.java
index 5b59eb8..1445001 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetDerivedFromClassNameFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetDerivedFromClassNameFactoryTest.java
@@ -28,11 +28,11 @@ import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryJUnit4TestCase;
 import org.apache.isis.core.metamodel.facets.ObjectSpecIdFacetFactory;
 import org.apache.isis.core.metamodel.facets.object.objectspecid.classname.ObjectSpecIdFacetDerivedFromClassName;
 import org.apache.isis.core.metamodel.facets.object.objectspecid.classname.ObjectSpecIdFacetDerivedFromClassNameFactory;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 
 public class ObjectSpecIdFacetDerivedFromClassNameFactoryTest extends AbstractFacetFactoryJUnit4TestCase {
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/id/TypeIdentifierTestFactory.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/id/TypeIdentifierTestFactory.java
index 58c8459..d61e419 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/id/TypeIdentifierTestFactory.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/id/TypeIdentifierTestFactory.java
@@ -18,7 +18,7 @@
  */
 package org.apache.isis.core.metamodel.id;
 
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 
 import lombok.experimental.UtilityClass;
 
@@ -27,8 +27,8 @@ public final class TypeIdentifierTestFactory {
     
     private static class Customer {};
     
-    public static TypeIdentifier newCustomer() {
-        return TypeIdentifier.fqcn(Customer.class);
+    public static LogicalType newCustomer() {
+        return LogicalType.fqcn(Customer.class);
     }
 
 }
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_constructor.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_constructor.java
index 3cc3e22..402f616 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_constructor.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_constructor.java
@@ -20,6 +20,8 @@ package org.apache.isis.core.metamodel.spec;
 
 import org.junit.Test;
 
+import org.apache.isis.applib.id.ObjectSpecId;
+
 public class ObjectSpecIdTest_constructor {
 
     @Test
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_valueSemantics.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_valueSemantics.java
index be0337a..b3808d7 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_valueSemantics.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/spec/ObjectSpecIdTest_valueSemantics.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.spec;
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.internaltestsupport.contract.ValueTypeContractTestAbstract;
 
 public class ObjectSpecIdTest_valueSemantics extends ValueTypeContractTestAbstract<ObjectSpecId> {
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/SpecificationCacheDefaultTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/SpecificationCacheDefaultTest.java
index 4618e32..96d2850 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/SpecificationCacheDefaultTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/SpecificationCacheDefaultTest.java
@@ -30,14 +30,18 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertSame;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2.Mode;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.core.metamodel.adapter.oid.LogicalTypeTestFactory;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 
 import lombok.val;
 
 public class SpecificationCacheDefaultTest {
+    
+    private LogicalType cus = LogicalTypeTestFactory.cus();
+    private LogicalType ord = LogicalTypeTestFactory.ord();
 
     @Rule
     public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_ONLY);
@@ -48,7 +52,7 @@ public class SpecificationCacheDefaultTest {
     private ObjectSpecification orderSpec;
 
     private SpecificationCache<ObjectSpecification> specificationCache = new SpecificationCacheDefault<>();
-    private SpecIdToClassResolver specIdToClassResolver = new SpecIdToClassResolverDefault();
+    private LogicalTypeResolver specIdToClassResolver = new LogicalTypeResolverDefault();
 
     @Before
     public void setUp() throws Exception {
@@ -57,14 +61,14 @@ public class SpecificationCacheDefaultTest {
             allowing(customerSpec).getCorrespondingClass();
             will(returnValue(Customer.class));
 
-            allowing(customerSpec).getSpecId();
-            will(returnValue(ObjectSpecId.of("CUS")));
+            allowing(customerSpec).getLogicalType();
+            will(returnValue(cus));
             
             allowing(orderSpec).getCorrespondingClass();
             will(returnValue(Order.class));
             
-            allowing(orderSpec).getSpecId();
-            will(returnValue(ObjectSpecId.of("ORD")));
+            allowing(orderSpec).getLogicalType();
+            will(returnValue(ord));
             
         }});
     }
@@ -106,7 +110,7 @@ public class SpecificationCacheDefaultTest {
 
     @Test
     public void getByObjectType_whenNotSet() {
-        val type = specIdToClassResolver.lookup(ObjectSpecId.of("CUS"));
+        val type = specIdToClassResolver.lookup(cus.getLogicalTypeName());
         assertFalse(type.isPresent());
     }
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
index 5db08f4..c0f2881 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
@@ -27,7 +27,7 @@ import java.util.Set;
 import java.util.stream.Stream;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.metamodel.BeanSort;
 import org.apache.isis.commons.collections.ImmutableEnumSet;
 import org.apache.isis.commons.internal.collections._Lists;
@@ -42,7 +42,6 @@ import org.apache.isis.core.metamodel.interactions.ObjectTitleContext;
 import org.apache.isis.core.metamodel.interactions.ObjectValidityContext;
 import org.apache.isis.core.metamodel.spec.ActionType;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.MixedIn;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
@@ -50,18 +49,21 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
 import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
 import org.apache.isis.core.metamodel.specloader.specimpl.IntrospectionState;
 
+import lombok.Synchronized;
 import lombok.val;
 
-public class ObjectSpecificationStub extends FacetHolderImpl implements ObjectSpecification {
+public class ObjectSpecificationStub 
+extends FacetHolderImpl
+implements ObjectSpecification {
 
     private ObjectAction action;
     public List<ObjectAssociation> fields = _Lists.newArrayList();
     private Set<ObjectSpecification> subclasses = Collections.emptySet();
     private String title;
     /**
-     * lazily derived, see {@link #getSpecId()} 
+     * lazily derived, see {@link #getLogicalType()} 
      */
-    private ObjectSpecId specId;
+    private LogicalType logicalType;
 
     private ObjectSpecification elementSpecification;
     private final Class<?> correspondingClass;
@@ -126,12 +128,14 @@ public class ObjectSpecificationStub extends FacetHolderImpl implements ObjectSp
         return name;
     }
 
+    @Synchronized
     @Override
-    public ObjectSpecId getSpecId() {
-        if(specId == null) {
-            specId = getFacet(ObjectSpecIdFacet.class).value();
+    public LogicalType getLogicalType() {
+        if(logicalType == null) {
+            val logicalTypeName = getFacet(ObjectSpecIdFacet.class).value().asString();
+            logicalType = LogicalType.eager(correspondingClass, logicalTypeName);
         }
-        return specId;
+        return logicalType;
     }
 
     @Override
@@ -257,7 +261,7 @@ public class ObjectSpecificationStub extends FacetHolderImpl implements ObjectSp
 
     @Override
     public Identifier getIdentifier() {
-        return Identifier.classIdentifier(TypeIdentifier.fqcn(correspondingClass));
+        return Identifier.classIdentifier(LogicalType.fqcn(correspondingClass));
     }
 
     @Override
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMemento.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMemento.java
index a3b62db..56b8071 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMemento.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMemento.java
@@ -24,19 +24,19 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Optional;
 
+import org.apache.isis.applib.id.HasLogicalType;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.commons.collections.Cardinality;
 import org.apache.isis.commons.internal.collections._Lists;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
-
 
 /**
  * @since 2.0
  */
-public interface ObjectMemento extends Serializable {
+public interface ObjectMemento extends HasLogicalType, Serializable {
 
     String asString();
-
+    
     /**
      * Returns a bookmark only if 
      * {@link org.apache.isis.viewer.wicket.viewer.services.mementos.ObjectMementoWkt.RecreateStrategy#LOOKUP} and
@@ -52,20 +52,18 @@ public interface ObjectMemento extends Serializable {
      * Returns {@code null} otherwise. 
      */
     Bookmark asHintingBookmarkIfSupported();
-
-    ObjectSpecId getObjectSpecId();
-
+    
     // -- FACTORIES
 
     static ObjectMemento wrapMementoList(
             Collection<ObjectMemento> container, 
-            ObjectSpecId specId) {
+            LogicalType logicalType) {
 
         // ArrayList is serializable
         if(container instanceof ArrayList) {
-            return ObjectMementoCollection.of((ArrayList<ObjectMemento>)container, specId);
+            return ObjectMementoCollection.of((ArrayList<ObjectMemento>)container, logicalType);
         }
-        return ObjectMementoCollection.of(_Lists.newArrayList(container), specId);
+        return ObjectMementoCollection.of(_Lists.newArrayList(container), logicalType);
     }
 
     // ArrayList is serializable
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMementoCollection.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMementoCollection.java
index 8c583ab..9ea8a2d 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMementoCollection.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMementoCollection.java
@@ -20,11 +20,12 @@ package org.apache.isis.core.runtime.memento;
 
 import java.util.ArrayList;
 
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 
 import lombok.Getter;
+import lombok.NonNull;
 import lombok.Value;
 
 /**
@@ -38,8 +39,10 @@ public final class ObjectMementoCollection implements ObjectMemento {
     private static final long serialVersionUID = 1L;
 
     private final ArrayList<ObjectMemento> container; 
-    @Getter(onMethod = @__({@Override})) private final ObjectSpecId objectSpecId;
 
+    @Getter(onMethod_ = {@Override})
+    @NonNull private final LogicalType logicalType;
+    
     @Override
     public String asString() {
         return getContainer().toString();
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMementoForEmpty.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMementoForEmpty.java
index 7937cb0..adbcee7 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMementoForEmpty.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMementoForEmpty.java
@@ -18,8 +18,8 @@
  */
 package org.apache.isis.core.runtime.memento;
 
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 
 import lombok.Getter;
 import lombok.NonNull;
@@ -30,14 +30,14 @@ public class ObjectMementoForEmpty implements ObjectMemento {
 
     private static final long serialVersionUID = 1L;
     
-    @Getter(onMethod = @__(@Override))
-    @NonNull private ObjectSpecId objectSpecId;
+    @Getter(onMethod_ = {@Override})
+    @NonNull private LogicalType logicalType;
 
     @Override
     public String asString() {
-        return getObjectSpecId().asString();
+        return getLogicalTypeName();
     }
-
+    
     @Override
     public Bookmark asBookmarkIfSupported() {
         return null;
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMementoService.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMementoService.java
index 2c9be7f..4c2bd75 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMementoService.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/memento/ObjectMementoService.java
@@ -18,16 +18,14 @@
  */
 package org.apache.isis.core.runtime.memento;
 
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 
 import lombok.NonNull;
 
 /**
  * @since 2.0
- * 
- *
  */
 public interface ObjectMementoService {
 
@@ -37,7 +35,7 @@ public interface ObjectMementoService {
 
     ObjectMemento mementoForPojo(Object pojo);
     
-    ObjectMemento mementoForPojos(Iterable<Object> iterablePojos, ObjectSpecId specId);
+    ObjectMemento mementoForPojos(Iterable<Object> iterablePojos, LogicalType logicalType);
 
     ManagedObject reconstructObject(ObjectMemento memento);
 
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/bookmarks/BookmarkServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/bookmarks/BookmarkServiceDefault.java
index d09ec39..12c8bc9 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/bookmarks/BookmarkServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/bookmarks/BookmarkServiceDefault.java
@@ -44,7 +44,6 @@ import org.apache.isis.commons.internal.memento._Mementos.SerializingAdapter;
 import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
 import org.apache.isis.core.metamodel.objectmanager.load.ObjectLoader;
 import org.apache.isis.core.metamodel.spec.ManagedObjects;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 
 import lombok.val;
@@ -79,7 +78,7 @@ public class BookmarkServiceDefault implements BookmarkService, SerializingAdapt
             return null;
         }
         try {
-            val spec = specificationLoader.loadSpecification(ObjectSpecId.of(bookmark.getObjectType()));
+            val spec = specificationLoader.loadSpecification(bookmark);
             val identifier = bookmark.getIdentifier();
             val objectLoadRequest = ObjectLoader.Request.of(spec, identifier);
             
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
index ee1162e..adb0c42 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
@@ -387,7 +387,7 @@ public class CommandExecutorServiceDefault implements CommandExecutorService {
     }
 
     private ManagedObject adapterFor(final RootOid oid) {
-        val objectSpec = specificationLoader.loadSpecification(oid.getObjectSpecId());
+        val objectSpec = specificationLoader.loadSpecification(oid.getLogicalTypeName());
         val loadRequest = ObjectLoader.Request.of(objectSpec, oid.getIdentifier());
         return objectSpec.getMetaModelContext().getObjectManager().loadObject(loadRequest);
     }
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java
index 2352337..1b62e8c 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/seed/scripts/AbstractRoleAndPermissionsFixtureScript.java
@@ -25,9 +25,9 @@ import java.util.stream.Collectors;
 
 import javax.inject.Inject;
 
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
-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.extensions.secman.api.permission.ApplicationPermissionMode;
diff --git a/extensions/vw/fullcalendar/ui/src/main/java/org/apache/isis/extensions/fullcalendar/ui/component/FullCalendarWithEventHandling.java b/extensions/vw/fullcalendar/ui/src/main/java/org/apache/isis/extensions/fullcalendar/ui/component/FullCalendarWithEventHandling.java
index a9407a5..9f31483 100644
--- a/extensions/vw/fullcalendar/ui/src/main/java/org/apache/isis/extensions/fullcalendar/ui/component/FullCalendarWithEventHandling.java
+++ b/extensions/vw/fullcalendar/ui/src/main/java/org/apache/isis/extensions/fullcalendar/ui/component/FullCalendarWithEventHandling.java
@@ -70,7 +70,7 @@ final class FullCalendarWithEventHandling extends FullCalendar {
         final ObjectManager objectManager = commonContext.getObjectManager();
         final IsisAppCommonContext webAppCommonContext = IsisAppCommonContext.of(metaModelContext);
 
-        val spec = specificationLoader.loadSpecification(oid.getObjectSpecId());
+        val spec = specificationLoader.loadSpecification(oid.getLogicalTypeName());
         val objectId = oid.getIdentifier();
         val managedObject = objectManager.loadObject(ObjectLoader.Request.of(spec, objectId));
 
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 a8a757a..2357a6d 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
@@ -126,7 +126,7 @@ implements EntityFacet {
 
         _Assert.assertTrue(entitySpec.isEntity());
 
-        val rootOid = Oid.Factory.root(entitySpec.getSpecId(), identifier);
+        val rootOid = Oid.Factory.root(entitySpec.getLogicalType(), identifier);
 
         log.debug("fetchEntity; rootOid={}", rootOid);
 
diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/object/query/VisitorForClauseAbstract.java b/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/object/query/VisitorForClauseAbstract.java
index 1aa95f3..65060d5 100644
--- a/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/object/query/VisitorForClauseAbstract.java
+++ b/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/object/query/VisitorForClauseAbstract.java
@@ -19,9 +19,8 @@
 package org.apache.isis.persistence.jdo.metamodel.facets.object.query;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.internal.base._Strings;
-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.metamodel.specloader.validator.MetaModelValidator;
@@ -80,10 +79,10 @@ abstract class VisitorForClauseAbstract implements MetaModelValidatorVisiting.Vi
         }
 
         val cls = objectSpec.getCorrespondingClass();
-        if (getSpecificationLoader().loadSpecification(ObjectSpecId.of(classNameFromClause))==null) {
+        if (getSpecificationLoader().loadSpecification(classNameFromClause)==null) {
             validator.onFailure(
                     objectSpec,
-                    Identifier.classIdentifier(TypeIdentifier.fqcn(cls)),
+                    Identifier.classIdentifier(LogicalType.fqcn(cls)),
                     "%s: error in JDOQL query, class name for '%s' clause not recognized (JDOQL : %s)",
                     cls.getName(), clause, query);
             return;
diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/object/query/VisitorForFromClause.java b/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/object/query/VisitorForFromClause.java
index ac9747e..1529cdc 100644
--- a/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/object/query/VisitorForFromClause.java
+++ b/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/object/query/VisitorForFromClause.java
@@ -21,9 +21,8 @@ package org.apache.isis.persistence.jdo.metamodel.facets.object.query;
 import java.util.Objects;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.core.metamodel.spec.Hierarchical;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidator;
 
@@ -52,14 +51,14 @@ class VisitorForFromClause extends VisitorForClauseAbstract {
         if (Objects.equals(classNameFromClause, cls.getName())) {
             return;
         }
-        val fromSpec = getSpecificationLoader().loadSpecification(ObjectSpecId.of(classNameFromClause));
+        val fromSpec = getSpecificationLoader().loadSpecification(classNameFromClause);
         val subclasses = fromSpec.subclasses(Hierarchical.Depth.TRANSITIVE);
         if(subclasses.contains(objectSpec)) {
             return;
         }
         validator.onFailure(
                 objectSpec,
-                Identifier.classIdentifier(TypeIdentifier.fqcn(cls)),
+                Identifier.classIdentifier(LogicalType.fqcn(cls)),
                 "%s: error in JDOQL query, class name after '%s' clause should be same as class name on which annotated, or one of its supertypes (JDOQL : %s)",
                 cls.getName(), clause, query);
     }
diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/object/query/VisitorForVariablesClause.java b/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/object/query/VisitorForVariablesClause.java
index 7987dfe..79eb0f4 100644
--- a/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/object/query/VisitorForVariablesClause.java
+++ b/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/facets/object/query/VisitorForVariablesClause.java
@@ -19,8 +19,7 @@
 package org.apache.isis.persistence.jdo.metamodel.facets.object.query;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.specimpl.IntrospectionState;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidator;
@@ -50,7 +49,7 @@ class VisitorForVariablesClause extends VisitorForClauseAbstract {
         val cls = objectSpec.getCorrespondingClass();
         val objectSpecification = getSpecificationLoader()
                 .loadSpecification(
-                        ObjectSpecId.of(classNameFromClause), 
+                        classNameFromClause, 
                         IntrospectionState.TYPE_INTROSPECTED);
         
         JdoPersistenceCapableFacet persistenceCapableFacet =
@@ -59,7 +58,7 @@ class VisitorForVariablesClause extends VisitorForClauseAbstract {
         if(persistenceCapableFacet == null) {
             validator.onFailure(
                     objectSpec,
-                    Identifier.classIdentifier(TypeIdentifier.fqcn(cls)),
+                    Identifier.classIdentifier(LogicalType.fqcn(cls)),
                     "%s: error in JDOQL query, class name for '%s' clause is not annotated as @PersistenceCapable (JDOQL : %s)",
                     cls.getName(), clause, query);
             return;
diff --git a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/discriminator/GivenJdoDiscriminatorAnnotationFacetFactoryTest.java b/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/discriminator/GivenJdoDiscriminatorAnnotationFacetFactoryTest.java
index c50efcd..f2dd166 100644
--- a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/discriminator/GivenJdoDiscriminatorAnnotationFacetFactoryTest.java
+++ b/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/discriminator/GivenJdoDiscriminatorAnnotationFacetFactoryTest.java
@@ -21,12 +21,12 @@ package org.apache.isis.persistence.jdo.metamodel.facets.object.discriminator;
 import javax.jdo.annotations.Discriminator;
 import javax.jdo.annotations.PersistenceCapable;
 
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.FacetFactory;
 import org.apache.isis.core.metamodel.facets.ObjectSpecIdFacetFactory;
 import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.persistence.jdo.metamodel.testing.AbstractFacetFactoryTest;
 import org.apache.isis.persistence.jdo.provider.metamodel.facets.object.discriminator.JdoDiscriminatorFacet;
 
diff --git a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/TypeIdentifierTestFactory.java b/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/TypeIdentifierTestFactory.java
index 22a3868..c0be502 100644
--- a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/TypeIdentifierTestFactory.java
+++ b/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/TypeIdentifierTestFactory.java
@@ -18,14 +18,14 @@
  */
 package org.apache.isis.persistence.jdo.metamodel.facets.object.version;
 
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 
 final class TypeIdentifierTestFactory {
 
     private static class Customer {};
     
-    static TypeIdentifier customer() {
-        return TypeIdentifier.fqcn(Customer.class);
+    static LogicalType customer() {
+        return LogicalType.fqcn(Customer.class);
     }
     
 }
diff --git a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/testing/AbstractFacetFactoryTest.java b/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/testing/AbstractFacetFactoryTest.java
index ea70fe7..38e4d2b 100644
--- a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/testing/AbstractFacetFactoryTest.java
+++ b/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/testing/AbstractFacetFactoryTest.java
@@ -26,7 +26,7 @@ import org.jmock.Expectations;
 import org.junit.Rule;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.repository.EntityState;
 import org.apache.isis.commons.collections.ImmutableEnumSet;
@@ -99,7 +99,7 @@ public abstract class AbstractFacetFactoryTest extends TestCase {
         // PRODUCTION
 
         facetHolder = new IdentifiedHolderImpl(
-                Identifier.propertyOrCollectionIdentifier(TypeIdentifier.fqcn(Customer.class), "firstName"));
+                Identifier.propertyOrCollectionIdentifier(LogicalType.fqcn(Customer.class), "firstName"));
         facetedMethod = FacetedMethod.createForProperty(Customer.class, "firstName");
         facetedMethodParameter = new FacetedMethodParameter(
                 FeatureType.ACTION_PARAMETER_SCALAR, facetedMethod.getOwningType(), facetedMethod.getMethod(), String.class
diff --git a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/domainmodel/SpecLoaderTest.java b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/domainmodel/SpecLoaderTest.java
index 45fd7e2..3763cbe 100644
--- a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/domainmodel/SpecLoaderTest.java
+++ b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/domainmodel/SpecLoaderTest.java
@@ -64,12 +64,12 @@ class SpecLoaderTest {
         val spec1 = specificationLoader.loadSpecification(type);
         assertNotNull(spec1);
         
-        val specId = spec1.getSpecId();
+        val logicalType = spec1.getLogicalType();
         
-        val spec2 = specificationLoader.loadSpecification(specId);
+        val spec2 = specificationLoader.loadSpecification(logicalType);
         assertNotNull(spec2);
         
-        assertEquals(spec1.getSpecId(), spec2.getSpecId());
+        assertEquals(spec1.getLogicalType(), spec2.getLogicalType());
     }
     
     private static Stream<Class<?>> providePrimitiveTypes() {
diff --git a/security/shiro/src/main/java/org/apache/isis/security/shiro/authorization/AuthorizorShiro.java b/security/shiro/src/main/java/org/apache/isis/security/shiro/authorization/AuthorizorShiro.java
index c54f3a8..9dc9214 100644
--- a/security/shiro/src/main/java/org/apache/isis/security/shiro/authorization/AuthorizorShiro.java
+++ b/security/shiro/src/main/java/org/apache/isis/security/shiro/authorization/AuthorizorShiro.java
@@ -87,7 +87,7 @@ public class AuthorizorShiro implements Authorizor {
     }
 
     private String asPermissionsString(Identifier identifier) {
-        val logicalTypeName = identifier.getTypeIdentifier().getLogicalTypeNameFormatted(":", ":");
+        val logicalTypeName = identifier.getLogicalType().getLogicalTypeNameFormatted(":", ":");
         return logicalTypeName + ":" + identifier.getMemberName();
     }
 
diff --git a/security/shiro/src/test/java/org/apache/isis/security/shiro/TypeIdentifierTestFactory.java b/security/shiro/src/test/java/org/apache/isis/security/shiro/TypeIdentifierTestFactory.java
index 7fa0571..5943a9d 100644
--- a/security/shiro/src/test/java/org/apache/isis/security/shiro/TypeIdentifierTestFactory.java
+++ b/security/shiro/src/test/java/org/apache/isis/security/shiro/TypeIdentifierTestFactory.java
@@ -18,16 +18,16 @@
  */
 package org.apache.isis.security.shiro;
 
-import org.apache.isis.applib.id.TypeIdentifier;
+import org.apache.isis.applib.id.LogicalType;
 
 final class TypeIdentifierTestFactory {
 
-    static TypeIdentifier customer() {
-        return TypeIdentifier.fqcn(Customer.class);
+    static LogicalType customer() {
+        return LogicalType.fqcn(Customer.class);
     }
     
-    static TypeIdentifier order() {
-        return TypeIdentifier.fqcn(Order.class);
+    static LogicalType order() {
+        return LogicalType.fqcn(Order.class);
     }
     
 }
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/mementos/ActionMemento.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/mementos/ActionMemento.java
index 59e3206..61a710b 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/mementos/ActionMemento.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/mementos/ActionMemento.java
@@ -22,8 +22,8 @@ package org.apache.isis.viewer.common.model.mementos;
 import java.io.Serializable;
 import java.util.function.Supplier;
 
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ActionType;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 
@@ -93,7 +93,7 @@ public class ActionMemento implements Serializable {
             String nameParmsId,
             SpecificationLoader specificationLoader) {
         
-        val objectSpec = specificationLoader.lookupBySpecIdElseLoad(owningType);
+        val objectSpec = specificationLoader.lookupBySpecIdElseLoad(owningType.asString());
         return objectSpec.getActionElseFail(nameParmsId, actionType);
     }
 
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModelProvider.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModelProvider.java
index 6768409..6287986 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModelProvider.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModelProvider.java
@@ -27,10 +27,10 @@ import javax.inject.Inject;
 import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facets.object.domainservicelayout.DomainServiceLayoutFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 
 import lombok.val;
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
index 35504c1..7014cdd 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
@@ -24,6 +24,7 @@ import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.facets.object.domainservicelayout.DomainServiceLayoutFacet;
 import org.apache.isis.core.metamodel.facets.object.title.TitleFacet;
@@ -33,7 +34,6 @@ import org.apache.isis.core.metamodel.interactions.managed.ManagedProperty;
 import org.apache.isis.core.metamodel.services.ServiceUtil;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ManagedObjects;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.MixedIn;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
@@ -193,10 +193,9 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
                 representation.mapPut("serviceId", ServiceUtil.idOfAdapter(objectAdapter));
             } else {
                 rootOidIfAny.ifPresent(rootOid->{
-                    Optional.ofNullable(rootOid.getObjectSpecId())
-                    .map(ObjectSpecId::asString)
-                    .ifPresent(objectSpecIdLiteral->
-                        representation.mapPut("domainType", objectSpecIdLiteral));
+                    Optional.ofNullable(rootOid.getLogicalTypeName())
+                    .ifPresent(domainType->
+                        representation.mapPut("domainType", domainType));
                     representation.mapPut("instanceId", rootOid.getIdentifier());
                 });
             }
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoder.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoder.java
index 05beeae..b174731 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoder.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoder.java
@@ -38,12 +38,12 @@ import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-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.viewer.restfulobjects.applib.JsonRepresentation;
diff --git a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_appendValueAndFormat.java b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_appendValueAndFormat.java
index ebe44cf..e60aab1 100644
--- a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_appendValueAndFormat.java
+++ b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_appendValueAndFormat.java
@@ -36,9 +36,9 @@ import static org.hamcrest.MatcherAssert.assertThat;
 
 import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-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.applib.id.ObjectSpecId;
 import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 
diff --git a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java
index 219fc56..b976178 100644
--- a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java
+++ b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java
@@ -45,10 +45,10 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-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.applib.exceptions.recoverable.TextEntryParseException;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 
diff --git a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asObject.java b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asObject.java
index 70b38c7..18cfba1 100644
--- a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asObject.java
+++ b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asObject.java
@@ -34,9 +34,9 @@ import static org.junit.Assert.assertSame;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-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.applib.id.ObjectSpecId;
 import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
 
 public class JsonValueEncoderTest_asObject {
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
index 80e1990..8474e2c 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
@@ -39,6 +39,7 @@ import javax.ws.rs.core.Response;
 import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.applib.layout.component.ActionLayoutData;
 import org.apache.isis.applib.layout.component.CollectionLayoutData;
 import org.apache.isis.applib.layout.component.DomainObjectLayoutData;
@@ -60,7 +61,6 @@ import org.apache.isis.core.metamodel.interactions.managed.MemberInteraction.Acc
 import org.apache.isis.core.metamodel.interactions.managed.PropertyInteraction;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ManagedObjects.EntityUtil;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 import org.apache.isis.viewer.restfulobjects.applib.Rel;
@@ -114,7 +114,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
             throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.BAD_REQUEST, "Body is not a map; got %s", objectRepr);
         }
 
-        final ObjectSpecification domainTypeSpec = getSpecificationLoader().lookupBySpecIdElseLoad(ObjectSpecId.of(domainType));
+        final ObjectSpecification domainTypeSpec = getSpecificationLoader().lookupBySpecIdElseLoad(domainType);
         if (domainTypeSpec == null) {
             throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.BAD_REQUEST, "Could not determine type of domain object to persist (no class with domainType Id of '%s')", domainType);
         }
@@ -343,8 +343,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
             final String domainType,
             final String instanceId) {
         
-        val specId = ObjectSpecId.of(domainType);
-        val objectSpec = getSpecificationLoader().lookupBySpecIdElseLoad(specId);
+        val objectSpec = getSpecificationLoader().lookupBySpecIdElseLoad(domainType);
         val gridFacet = objectSpec.getFacet(GridFacet.class);
 
         if(gridFacet == null) {
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
index e84c6bf..cc7ebdc 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
@@ -36,7 +36,6 @@ import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.core.interaction.session.InteractionTracker;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facets.object.grid.GridFacet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
 import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
@@ -113,7 +112,7 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
         val resourceContext = createResourceContext(
                 RepresentationType.DOMAIN_TYPE, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
 
-        val objectSpec = getSpecificationLoader().lookupBySpecIdElseLoad(ObjectSpecId.of(domainType));
+        val objectSpec = getSpecificationLoader().lookupBySpecIdElseLoad(domainType);
 
         final DomainTypeReprRenderer renderer = new DomainTypeReprRenderer(resourceContext, null, JsonRepresentation.newMap());
         renderer.with(objectSpec).includesSelf();
@@ -135,7 +134,7 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
         
         val serializationStrategy = resourceContext.getSerializationStrategy();
 
-        val objectSpec = getSpecificationLoader().lookupBySpecIdElseLoad(ObjectSpecId.of(domainType));
+        val objectSpec = getSpecificationLoader().lookupBySpecIdElseLoad(domainType);
         val gridFacet = objectSpec.getFacet(GridFacet.class);
         
         final Response.ResponseBuilder builder;
@@ -160,7 +159,7 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
         val resourceContext = createResourceContext(
                 RepresentationType.PROPERTY_DESCRIPTION, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
 
-        val parentSpec = getSpecificationLoader().lookupBySpecIdElseLoad(ObjectSpecId.of(domainType));
+        val parentSpec = getSpecificationLoader().lookupBySpecIdElseLoad(domainType);
         if (parentSpec == null) {
             throw RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND);
         }
@@ -188,7 +187,7 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
         val resourceContext = createResourceContext(
                 RepresentationType.COLLECTION_DESCRIPTION, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
 
-        val parentSpec = getSpecificationLoader().lookupBySpecIdElseLoad(ObjectSpecId.of(domainType));
+        val parentSpec = getSpecificationLoader().lookupBySpecIdElseLoad(domainType);
         if (parentSpec == null) {
             throw RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND);
         }
@@ -216,7 +215,7 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
         val resourceContext = createResourceContext(
                 RepresentationType.ACTION_DESCRIPTION, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
 
-        val parentSpec = getSpecificationLoader().lookupBySpecIdElseLoad(ObjectSpecId.of(domainType));
+        val parentSpec = getSpecificationLoader().lookupBySpecIdElseLoad(domainType);
         if (parentSpec == null) {
             throw RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND);
         }
@@ -239,7 +238,7 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
         val resourceContext = createResourceContext(
                 RepresentationType.ACTION_PARAMETER_DESCRIPTION, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
 
-        val parentSpec = getSpecificationLoader().lookupBySpecIdElseLoad(ObjectSpecId.of(domainType));
+        val parentSpec = getSpecificationLoader().lookupBySpecIdElseLoad(domainType);
         if (parentSpec == null) {
             throw RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND);
         }
@@ -274,8 +273,8 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
 
         final String supertype = domainTypeFor(superTypeStr, argsUrlEncoded, "supertype");
 
-        val domainTypeSpec = getSpecificationLoader().lookupBySpecIdElseLoad(ObjectSpecId.of(domainType));
-        val supertypeSpec = getSpecificationLoader().lookupBySpecIdElseLoad(ObjectSpecId.of(supertype));
+        val domainTypeSpec = getSpecificationLoader().lookupBySpecIdElseLoad(domainType);
+        val supertypeSpec = getSpecificationLoader().lookupBySpecIdElseLoad(supertype);
 
         final TypeActionResultReprRenderer renderer = new TypeActionResultReprRenderer(resourceContext, null, JsonRepresentation.newMap());
 
@@ -306,8 +305,8 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
 
         final String subtype = domainTypeFor(subTypeStr, argsUrlEncoded, "subtype");
 
-        val domainTypeSpec = getSpecificationLoader().lookupBySpecIdElseLoad(ObjectSpecId.of(domainType));
-        val subtypeSpec = getSpecificationLoader().lookupBySpecIdElseLoad(ObjectSpecId.of(subtype));
+        val domainTypeSpec = getSpecificationLoader().lookupBySpecIdElseLoad(domainType);
+        val subtypeSpec = getSpecificationLoader().lookupBySpecIdElseLoad(subtype);
 
         final TypeActionResultReprRenderer renderer = new TypeActionResultReprRenderer(resourceContext, null, JsonRepresentation.newMap());
 
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java
index 56d776b..0fd6e96 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/links/LinkAndLabel.java
@@ -26,10 +26,10 @@ import java.util.List;
 import javax.annotation.Nullable;
 
 import org.apache.isis.applib.annotation.ActionLayout.Position;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.viewer.common.model.action.ActionUiMetaModel;
 import org.apache.isis.viewer.wicket.model.common.CommonContextUtils;
@@ -81,7 +81,7 @@ public final class LinkAndLabel extends LinkAndLabelAbstract {
         @NonNull  private final ActionLinkUiComponentFactoryWkt uiComponentFactory;
         @Nullable private final String named;
         @NonNull  private final EntityModel actionHolder;
-        @NonNull  private final ObjectSpecId actionHolderSpecId;
+        @NonNull  private final LogicalType actionHolderLogicalType;
         @NonNull  private final String objectActionId;
         
         private SerializationProxy(LinkAndLabel target) {
@@ -89,14 +89,14 @@ public final class LinkAndLabel extends LinkAndLabelAbstract {
             this.named = target.getNamed();
             this.actionHolder = (EntityModel) target.getActionHolder();
             // make sure we do this without side-effects
-            this.actionHolderSpecId = actionHolder.getTypeOfSpecificationId()
+            this.actionHolderLogicalType = actionHolder.getTypeOfSpecificationId()
                     .orElseThrow(_Exceptions::unexpectedCodeReach); 
             this.objectActionId = target.getObjectAction().getId();
         }
 
         private Object readResolve() {
             val commonContext = CommonContextUtils.getCommonContext();
-            val actionHolderSpec = commonContext.getSpecificationLoader().loadSpecification(actionHolderSpecId);
+            val actionHolderSpec = commonContext.getSpecificationLoader().loadSpecification(actionHolderLogicalType);
             val objectMember = actionHolderSpec
                     .getMember(objectActionId)
                     .orElseThrow(()->
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/CollectionMemento.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/CollectionMemento.java
index a213f37..856c27b 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/CollectionMemento.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/CollectionMemento.java
@@ -21,7 +21,7 @@ package org.apache.isis.viewer.wicket.model.mementos;
 
 import java.io.Serializable;
 
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
@@ -39,8 +39,8 @@ public class CollectionMemento implements Serializable {
     private static ObjectSpecification owningSpecFor(OneToManyAssociation association) {
         
         val specificationLoader = association.getMetaModelContext().getSpecificationLoader();
-        val specId = ObjectSpecId.of(association.getIdentifier().getClassName());
-        return specificationLoader.lookupBySpecIdElseLoad(specId);
+        val logicalType = association.getIdentifier().getLogicalTypeName();
+        return specificationLoader.lookupBySpecIdElseLoad(logicalType);
     }
 
     private final ObjectSpecId owningType;
@@ -103,7 +103,7 @@ public class CollectionMemento implements Serializable {
             ObjectSpecId owningType,
             String id,
             final SpecificationLoader specificationLoader) {
-        return (OneToManyAssociation) specificationLoader.lookupBySpecIdElseLoad(owningType)
+        return (OneToManyAssociation) specificationLoader.lookupBySpecIdElseLoad(owningType.asString())
                 .getAssociationElseFail(id);
     }
 
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/PropertyMemento.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/PropertyMemento.java
index b8f00ed..2f1b866 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/PropertyMemento.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/PropertyMemento.java
@@ -21,7 +21,7 @@ package org.apache.isis.viewer.wicket.model.mementos;
 
 import java.io.Serializable;
 
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
@@ -34,39 +34,37 @@ public class PropertyMemento implements Serializable {
     private static final long serialVersionUID = 1L;
 
     private static ObjectSpecification owningSpecFor(OneToOneAssociation property) {
-        
         val specificationLoader = property.getMetaModelContext().getSpecificationLoader();
-        return specificationLoader.lookupBySpecIdElseLoad(
-                ObjectSpecId.of(property.getIdentifier().getClassName()));
+        return specificationLoader.lookupBySpecIdElseLoad(property.getIdentifier().getLogicalType());
     }
 
-    private final ObjectSpecId owningSpecId;
+    private final LogicalType owningType;
     private final String identifier;
-    private final ObjectSpecId specId;
+    private final LogicalType type;
 
     public PropertyMemento(final OneToOneAssociation property) {
         this(
-                owningSpecFor(property).getSpecId(),
+                owningSpecFor(property).getLogicalType(),
                 property.getIdentifier().getMemberName(),
-                property.getSpecification().getSpecId()
+                property.getSpecification().getLogicalType()
                 );
     }
 
     private PropertyMemento(
-            final ObjectSpecId owningSpecId,
+            final LogicalType owningType,
             final String name,
-            final ObjectSpecId specId) {
-        this.owningSpecId = owningSpecId;
+            final LogicalType type) {
+        this.owningType = owningType;
         this.identifier = name;
-        this.specId = specId;
+        this.type = type;
     }
 
-    public ObjectSpecId getOwningType() {
-        return owningSpecId;
+    public LogicalType getOwningType() {
+        return owningType;
     }
 
-    public ObjectSpecId getType() {
-        return specId;
+    public LogicalType getType() {
+        return type;
     }
 
     public String getIdentifier() {
@@ -74,11 +72,11 @@ public class PropertyMemento implements Serializable {
     }
 
     public OneToOneAssociation getProperty(final SpecificationLoader specificationLoader) {
-        return propertyFor(owningSpecId, identifier, specificationLoader);
+        return propertyFor(owningType, identifier, specificationLoader);
     }
 
     private static OneToOneAssociation propertyFor(
-            ObjectSpecId owningType,
+            LogicalType owningType,
             String identifier,
             final SpecificationLoader specificationLoader) {
         
@@ -124,7 +122,7 @@ public class PropertyMemento implements Serializable {
 
     @Override
     public String toString() {
-        return getOwningType().asString() + "#" + getIdentifier();
+        return getOwningType().getLogicalTypeName() + "#" + getIdentifier();
     }
 
 }
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkTreeNodeComparator.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkTreeNodeComparator.java
index 87b741d..f7a2f90 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkTreeNodeComparator.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BookmarkTreeNodeComparator.java
@@ -22,7 +22,6 @@ package org.apache.isis.viewer.wicket.model.models;
 import java.util.Comparator;
 
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 
 final class BookmarkTreeNodeComparator implements Comparator<BookmarkTreeNode> {
@@ -63,8 +62,7 @@ final class BookmarkTreeNodeComparator implements Comparator<BookmarkTreeNode> {
     }
 
     private String classNameOf(RootOid oid) {
-        ObjectSpecId objectSpecId = oid.getObjectSpecId();
-        return specificationLoader.lookupBySpecIdElseLoad(objectSpecId)
+        return specificationLoader.lookupBySpecIdElseLoad(oid.getLogicalTypeName())
                 .getIdentifier().getClassName();
     }
 
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ManagedObjectModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ManagedObjectModel.java
index 5e9d69e..41b3c53 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ManagedObjectModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ManagedObjectModel.java
@@ -24,6 +24,8 @@ import java.util.Optional;
 import javax.annotation.Nullable;
 
 import org.apache.isis.applib.annotation.BookmarkPolicy;
+import org.apache.isis.applib.id.LogicalType;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.collections._Collections;
@@ -31,7 +33,6 @@ import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facets.object.bookmarkpolicy.BookmarkPolicyFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ManagedObjects;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.runtime.context.IsisAppCommonContext;
 import org.apache.isis.core.runtime.memento.ObjectMemento;
@@ -104,7 +105,7 @@ extends ModelAbstract<ManagedObject> {
         val pojos = adapter.getPojo();
         memento = super.getMementoService()
                 .mementoForPojos(_Casts.uncheckedCast(pojos), getTypeOfSpecificationId()
-                        .orElseGet(()->adapter.getElementSpecification().get().getSpecId()));
+                        .orElseGet(()->adapter.getElementSpecification().get().getLogicalType()));
     }
     
     public final Bookmark asHintingBookmarkIfSupported() {
@@ -128,10 +129,11 @@ extends ModelAbstract<ManagedObject> {
     /**
      * free of side-effects, used for serialization
      * @implNote overriding this must be consistent with {@link #getTypeOfSpecification()}
+     * TODO[2553] rename to getLogicalElementType
      */
-    public Optional<ObjectSpecId> getTypeOfSpecificationId() {
+    public Optional<LogicalType> getTypeOfSpecificationId() {
         return Optional.ofNullable(memento)
-                .map(ObjectMemento::getObjectSpecId);
+                .map(ObjectMemento::getLogicalType);
     }
     
     private transient ObjectSpecification objectSpec;
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/PageParameterUtil.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/PageParameterUtil.java
index e70e686..809cf80 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/PageParameterUtil.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/PageParameterUtil.java
@@ -25,6 +25,7 @@ import java.util.regex.Pattern;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.primitives._Ints;
 import org.apache.isis.core.metamodel.adapter.oid.Oid;
@@ -33,7 +34,6 @@ import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
 import org.apache.isis.core.metamodel.spec.ActionType;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ManagedObjects;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
index bc8b7c0..dde6c25 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Optional;
 
 import org.apache.isis.applib.annotation.PromptStyle;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.collections._Lists;
@@ -31,7 +32,6 @@ import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facets.object.parseable.ParseableFacet;
 import org.apache.isis.core.metamodel.facets.object.promptStyle.PromptStyleFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.viewer.common.model.feature.ScalarUiModel;
@@ -160,8 +160,9 @@ implements HasRenderingHints, ScalarUiModel, LinksProvider, FormExecutorContext
     }
 
     @Override
-    public Optional<ObjectSpecId> getTypeOfSpecificationId() {
-        return Optional.of(getScalarTypeSpec().getSpecId());
+    public Optional<LogicalType> getTypeOfSpecificationId() {
+        return Optional.ofNullable(getScalarTypeSpec())
+                .map(ObjectSpecification::getLogicalType);
     }
     
 
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModelWithMultiPending.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModelWithMultiPending.java
index 03f4470..066084a 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModelWithMultiPending.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModelWithMultiPending.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 
 import org.apache.wicket.model.Model;
 
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.runtime.memento.ObjectMemento;
 
 import lombok.val;
@@ -63,8 +62,8 @@ public interface ScalarModelWithMultiPending extends Serializable {
 
                 @Override
                 public void setMultiPending(final ArrayList<ObjectMemento> pending) {
-                    ObjectSpecId specId = getScalarModel().getTypeOfSpecification().getSpecId();
-                    ObjectMemento adapterMemento = ObjectMemento.wrapMementoList(pending, specId);
+                    val logicalType = getScalarModel().getTypeOfSpecification().getLogicalType();
+                    ObjectMemento adapterMemento = ObjectMemento.wrapMementoList(pending, logicalType);
                     scalarModel.getPendingModel().setObject(adapterMemento);
                 }
 
@@ -108,9 +107,9 @@ public interface ScalarModelWithMultiPending extends Serializable {
                         final ArrayList<ObjectMemento> ownerPending = owner.getMultiPending();
                         if (ownerPending != null) {
                             log.debug("setting to pending: {}", ownerPending.toString());
-                            final ObjectSpecId objectSpecId = ownerScalarModel.getTypeOfSpecification().getSpecId();
+                            val logicalType = ownerScalarModel.getTypeOfSpecification().getLogicalType();
                             ownerScalarModel.memento(
-                                    ObjectMemento.wrapMementoList(adapterMemento, objectSpecId));
+                                    ObjectMemento.wrapMementoList(adapterMemento, logicalType));
                         }
                     }
                 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.java
index 709a779..6379bc5 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/bookmarkedpages/BookmarkedPagesPanel.java
@@ -43,8 +43,8 @@ import org.apache.wicket.request.resource.ResourceReference;
 import org.apache.wicket.util.string.Strings;
 
 import org.apache.isis.applib.exceptions.unrecoverable.ObjectNotFoundException;
+import org.apache.isis.applib.id.ObjectSpecId;
 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.viewer.wicket.model.models.BookmarkTreeNode;
 import org.apache.isis.viewer.wicket.model.models.BookmarkedPagesModel;
@@ -164,8 +164,7 @@ public class BookmarkedPagesPanel extends PanelAbstract<BookmarkedPagesModel> {
                     ObjectSpecification objectSpec = null;
                     RootOid oid = node.getOidNoVer();
                     if(oid != null) {
-                        ObjectSpecId objectSpecId = oid.getObjectSpecId();
-                        objectSpec = getSpecificationLoader().lookupBySpecIdElseLoad(objectSpecId);
+                        objectSpec = getSpecificationLoader().lookupBySpecIdElseLoad(oid.getLogicalTypeName());
                     }
                     final ResourceReference imageResource = getImageResourceCache().resourceReferenceForSpec(objectSpec);
                     final Image image = new Image(ID_BOOKMARKED_PAGE_ICON, imageResource) {
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelectAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelectAbstract.java
index e45def6..9700a17 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelectAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelectAbstract.java
@@ -239,9 +239,9 @@ public abstract class ScalarPanelSelectAbstract extends ScalarPanelAbstract {
                     return;
                 }
                 val memento = proposedValueObjAsList.get(0);
-                val objectSpecId = memento.getObjectSpecId();
+                val logicalType = memento.getLogicalType();
                 proposedValue = ObjectMemento
-                        .wrapMementoList(proposedValueObjAsList, objectSpecId);
+                        .wrapMementoList(proposedValueObjAsList, logicalType);
             } else {
                 proposedValue = (ObjectMemento) proposedValueObj;
             }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/ChoiceExt.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/ChoiceExt.java
index 72f527e..1636f68 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/ChoiceExt.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/ChoiceExt.java
@@ -23,18 +23,18 @@ import org.wicketstuff.select2.Select2Choice;
 import org.wicketstuff.select2.Select2MultiChoice;
 import org.wicketstuff.select2.Settings;
 
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.applib.id.HasLogicalType;
 import org.apache.isis.core.runtime.memento.ObjectMemento;
 
 /**
  * Represents functionality that is common to both {@link Select2Choice} and {@link Select2MultiChoice}, but for
  * which there is no suitable common supertype.
  *
- * Also holds extensions, notable {@link #getSpecId()}.
  */
-public interface ChoiceExt {
+public interface ChoiceExt extends HasLogicalType {
+    
     void setProvider(final ChoiceProvider<ObjectMemento> providerForChoices);
     Settings getSettings();
 
-    ObjectSpecId getSpecId();
+    
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2.java
index cbe531d..ba3101a 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2.java
@@ -109,7 +109,7 @@ public class Select2 implements Serializable {
         } else {
             final Collection<ObjectMemento> modelObject = select2MultiChoice.getModelObject();
 
-            return ObjectMemento.wrapMementoList(modelObject, select2MultiChoice.getSpecId());
+            return ObjectMemento.wrapMementoList(modelObject, select2MultiChoice.getLogicalType());
         }
     }
 
@@ -120,7 +120,7 @@ public class Select2 implements Serializable {
             final IModel<Collection<ObjectMemento>> model = select2MultiChoice.getModel();
             final Collection<ObjectMemento> modelObject = model.getObject();
 
-            final ObjectMemento memento = ObjectMemento.wrapMementoList(modelObject, select2MultiChoice.getSpecId());
+            final ObjectMemento memento = ObjectMemento.wrapMementoList(modelObject, select2MultiChoice.getLogicalType());
             return new IModel<ObjectMemento>() {
                 private static final long serialVersionUID = 1L;
 
@@ -147,7 +147,7 @@ public class Select2 implements Serializable {
             return select2Choice.getConvertedInput();
         } else {
             final Collection<ObjectMemento> convertedInput = select2MultiChoice.getConvertedInput();
-            return ObjectMemento.wrapMementoList(convertedInput, select2MultiChoice.getSpecId());
+            return ObjectMemento.wrapMementoList(convertedInput, select2MultiChoice.getLogicalType());
         }
     }
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2ChoiceExt.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2ChoiceExt.java
index ef6d8cb..ef117b0 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2ChoiceExt.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2ChoiceExt.java
@@ -21,12 +21,16 @@ package org.apache.isis.viewer.wicket.ui.components.widgets.select2;
 import org.apache.wicket.model.IModel;
 import org.wicketstuff.select2.Select2Choice;
 
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.core.runtime.memento.ObjectMemento;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.components.widgets.select2.providers.EmptyChoiceProvider;
 
-public class Select2ChoiceExt extends Select2Choice<ObjectMemento> implements ChoiceExt {
+import lombok.Getter;
+
+public class Select2ChoiceExt 
+extends Select2Choice<ObjectMemento> 
+implements ChoiceExt {
     
     private static final long serialVersionUID = 1L;
 
@@ -37,22 +41,18 @@ public class Select2ChoiceExt extends Select2Choice<ObjectMemento> implements Ch
         return new Select2ChoiceExt(id, modelObject, scalarModel);
     }
 
-    private final ObjectSpecId specId;
+    @Getter(onMethod_ = {@Override}) private final LogicalType logicalType;
 
     private Select2ChoiceExt(
             final String id,
             final IModel<ObjectMemento> model,
             final ScalarModel scalarModel) {
         super(id, model, EmptyChoiceProvider.INSTANCE);
-        specId = scalarModel.getTypeOfSpecification().getSpecId();
+        logicalType = scalarModel.getTypeOfSpecification().getLogicalType();
 
         getSettings().setCloseOnSelect(true);
 
         setOutputMarkupPlaceholderTag(true);
     }
 
-    @Override
-    public ObjectSpecId getSpecId() {
-        return specId;
-    }
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2MultiChoiceExt.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2MultiChoiceExt.java
index 0abffb1..4a72397 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2MultiChoiceExt.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2MultiChoiceExt.java
@@ -24,17 +24,19 @@ import java.util.Collection;
 import org.apache.wicket.model.IModel;
 import org.wicketstuff.select2.Select2MultiChoice;
 
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.internal.base._Casts;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.runtime.memento.ObjectMemento;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.components.widgets.select2.providers.EmptyChoiceProvider;
 
+import lombok.Getter;
 import lombok.val;
 
 public class Select2MultiChoiceExt
 extends Select2MultiChoice<ObjectMemento>
-implements ChoiceExt {
+implements 
+    ChoiceExt {
 
     private static final long serialVersionUID = 1L;
 
@@ -46,8 +48,7 @@ implements ChoiceExt {
         return new Select2MultiChoiceExt(id, _Casts.uncheckedCast(modelObject), scalarModel);
     }
 
-    private final ObjectSpecId specId;
-    
+    @Getter(onMethod_ = {@Override}) private final LogicalType logicalType;
 
     Select2MultiChoiceExt(
             final String id,
@@ -55,17 +56,13 @@ implements ChoiceExt {
             final ScalarModel scalarModel) {
         
         super(id, model, EmptyChoiceProvider.INSTANCE);
-        specId = scalarModel.getTypeOfSpecification().getSpecId();
+        logicalType = scalarModel.getTypeOfSpecification().getLogicalType();
 
         getSettings().setCloseOnSelect(true);
 
         setOutputMarkupPlaceholderTag(true);
     }
 
-    @Override
-    public ObjectSpecId getSpecId() {
-        return specId;
-    }
     
     // -- bug in wicket 8.8.0 -------------------------------------------
     
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/providers/ObjectAdapterMementoProviderAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/providers/ObjectAdapterMementoProviderAbstract.java
index 35c39d5..29909eb 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/providers/ObjectAdapterMementoProviderAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/providers/ObjectAdapterMementoProviderAbstract.java
@@ -87,14 +87,14 @@ extends ChoiceProvider<ObjectMemento> {
         if (choiceMemento == null) {
             return NULL_PLACEHOLDER;
         }
-        val objectSpecId = choiceMemento.getObjectSpecId();
+        val logicalType = choiceMemento.getLogicalType();
         val spec = getCommonContext().getSpecificationLoader()
-                .lookupBySpecIdElseLoad(objectSpecId);
+                .lookupBySpecIdElseLoad(logicalType);
 
         // support enums that are implementing an interface; only know this late in the day
         // TODO: this is a hack, really should push this deeper so that Encodeable OAMs also prefix themselves with their objectSpecId
         if(spec != null && spec.isEncodeable()) {
-            return objectSpecId.asString() + ":" + choiceMemento.asString();
+            return logicalType.getLogicalTypeName() + ":" + choiceMemento.asString();
         } else {
             return choiceMemento.asString();
         }
diff --git a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/widgets/valuechoices/ObjectAdapterMementoProviderForValueChoicesTest.java b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/widgets/valuechoices/ObjectAdapterMementoProviderForValueChoicesTest.java
index b897a2e..da99254 100644
--- a/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/widgets/valuechoices/ObjectAdapterMementoProviderForValueChoicesTest.java
+++ b/viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/widgets/valuechoices/ObjectAdapterMementoProviderForValueChoicesTest.java
@@ -30,9 +30,9 @@ import org.junit.Test;
 
 import static org.hamcrest.CoreMatchers.is;
 
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
-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.context.IsisAppCommonContext;
@@ -41,6 +41,8 @@ import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.components.widgets.select2.providers.ObjectAdapterMementoProviderForValueChoices;
 
+import lombok.val;
+
 public class ObjectAdapterMementoProviderForValueChoicesTest {
 
     @Rule public JUnitRuleMockery2 context = 
@@ -60,10 +62,12 @@ public class ObjectAdapterMementoProviderForValueChoicesTest {
 
     @Before
     public void setUp() throws Exception {
-        final ObjectSpecId fakeSpecId = ObjectSpecId.of("FAKE");
+        final String fakeSpecId = "FAKE";
+        
+        val fakeLocalType = LogicalType.lazy(getClass(), ()->fakeSpecId);
 
-        mockMemento1 = mock(fakeSpecId, "mockMemento1");
-        mockMemento2 = mock(fakeSpecId, "mockMemento2");
+        mockMemento1 = mock(fakeLocalType, "mockMemento1");
+        mockMemento2 = mock(fakeLocalType, "mockMemento2");
 
         mementos = Can.of(mockMemento1, mockMemento2);
         
@@ -78,7 +82,7 @@ public class ObjectAdapterMementoProviderForValueChoicesTest {
             allowing(mockCommonContext).getSpecificationLoader();
             will(returnValue(mockSpecificationLoader));
             
-            allowing(mockSpecificationLoader).lookupBySpecIdElseLoad(fakeSpecId);
+            allowing(mockSpecificationLoader).lookupBySpecIdElseLoad(fakeLocalType);
             will(returnValue(mockSpec));
 
             allowing(mockSpec).isEncodeable();
@@ -99,12 +103,12 @@ public class ObjectAdapterMementoProviderForValueChoicesTest {
     }
 
     private ObjectMemento mock(
-            final ObjectSpecId specId,
+            final LogicalType logicalType,
             final String id) {
         final ObjectMemento mock = context.mock(ObjectMemento.class, id);
         context.checking(new Expectations() {{
-            allowing(mock).getObjectSpecId();
-            will(returnValue(specId));
+            allowing(mock).getLogicalType();
+            will(returnValue(logicalType));
 
             allowing(mock).asString();
             will(returnValue(id));
diff --git a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/ConverterForObjectAdapter.java b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/ConverterForObjectAdapter.java
index f311abf..b5c9c5e 100644
--- a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/ConverterForObjectAdapter.java
+++ b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/ConverterForObjectAdapter.java
@@ -51,10 +51,9 @@ public class ConverterForObjectAdapter implements IConverter<ManagedObject> {
     @Override
     public ManagedObject convertToObject(final String value, final Locale locale) {
         val rootOid = RootOid.deStringEncoded(value);
-        val objectSpecId = rootOid.getObjectSpecId(); 
         val spec = objectManager.getMetaModelContext()
                 .getSpecificationLoader()
-                .lookupBySpecIdElseLoad(objectSpecId);
+                .lookupBySpecIdElseLoad(rootOid.getLogicalTypeName());
         
         val objectLoadRequest = ObjectLoader.Request.of(spec, rootOid.getIdentifier());
         
diff --git a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/mementos/ObjectMementoServiceWicket.java b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/mementos/ObjectMementoServiceWicket.java
index af24d8c..6f046ae 100644
--- a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/mementos/ObjectMementoServiceWicket.java
+++ b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/mementos/ObjectMementoServiceWicket.java
@@ -31,6 +31,7 @@ import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
@@ -39,7 +40,6 @@ import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ManagedObjects;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.core.runtime.memento.ObjectMemento;
 import org.apache.isis.core.runtime.memento.ObjectMementoCollection;
@@ -82,7 +82,7 @@ public class ObjectMementoServiceWicket implements ObjectMementoService {
         if(mementoAdapter==null) {
             // sonar-ignore-on (fails to detect this as null guard)
             return ManagedObjects.isSpecified(adapter)
-                    ? new ObjectMementoForEmpty(adapter.getSpecification().getSpecId())
+                    ? new ObjectMementoForEmpty(adapter.getSpecification().getLogicalType())
                     : null;
             // sonar-ignore-on
         }
@@ -95,7 +95,7 @@ public class ObjectMementoServiceWicket implements ObjectMementoService {
         assertSingleton(paramAdapter);
         val mementoAdapter = ObjectMementoWkt.createOrNull(paramAdapter);
         if(mementoAdapter==null) {
-            return new ObjectMementoForEmpty(paramAdapter.getSpecification().getSpecId());
+            return new ObjectMementoForEmpty(paramAdapter.getSpecification().getLogicalType());
         }
         return ObjectMementoAdapter.of(mementoAdapter);
     }
@@ -111,13 +111,13 @@ public class ObjectMementoServiceWicket implements ObjectMementoService {
     }
     
     @Override
-    public ObjectMemento mementoForPojos(Iterable<Object> iterablePojos, ObjectSpecId specId) {
+    public ObjectMemento mementoForPojos(Iterable<Object> iterablePojos, LogicalType logicalType) {
 //        _Probe.errOut("mementoForPojos");
         val listOfMementos = _NullSafe.stream(iterablePojos)
                 .map(pojo->mementoForPojo(pojo))
                 .collect(Collectors.toCollection(ArrayList::new)); // ArrayList is serializable
 
-        return ObjectMementoCollection.of(listOfMementos, specId);
+        return ObjectMementoCollection.of(listOfMementos, logicalType);
     }
 
     @Override
@@ -129,8 +129,8 @@ public class ObjectMementoServiceWicket implements ObjectMementoService {
         
         if(memento instanceof ObjectMementoForEmpty) {
             val objectMementoForEmpty = (ObjectMementoForEmpty) memento;
-            val specId = objectMementoForEmpty.getObjectSpecId();
-            val spec = specificationLoader.loadSpecification(specId);
+            val logicalType = objectMementoForEmpty.getLogicalType();
+            val spec = specificationLoader.loadSpecification(logicalType);
             return ManagedObject.empty(spec);
         }
         
@@ -196,10 +196,10 @@ public class ObjectMementoServiceWicket implements ObjectMementoService {
         public Bookmark asHintingBookmarkIfSupported() {
             return delegate.asHintingBookmark();
         }
-
+        
         @Override
-        public ObjectSpecId getObjectSpecId() {
-            return delegate.getObjectSpecId();
+        public LogicalType getLogicalType() {
+            return delegate.getLogicalType();
         }
 
         ManagedObject reconstructObject(MetaModelContext mmc) {
@@ -211,6 +211,8 @@ public class ObjectMementoServiceWicket implements ObjectMementoService {
             return delegate.toString();
         }
 
+
+
     }
 
 
diff --git a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/mementos/ObjectMementoWkt.java b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/mementos/ObjectMementoWkt.java
index 6ad0084..260416e 100644
--- a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/mementos/ObjectMementoWkt.java
+++ b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/mementos/ObjectMementoWkt.java
@@ -26,6 +26,8 @@ import java.util.List;
 import java.util.Objects;
 import java.util.function.Function;
 
+import org.apache.isis.applib.id.HasLogicalType;
+import org.apache.isis.applib.id.LogicalType;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.hint.HintIdProvider;
 import org.apache.isis.commons.internal.base._NullSafe;
@@ -37,20 +39,20 @@ import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ManagedObjects;
-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 static org.apache.isis.commons.internal.base._With.requires;
 
 import lombok.AccessLevel;
+import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.NonNull;
 import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
 @Log4j2
-final class ObjectMementoWkt implements Serializable {
+final class ObjectMementoWkt implements HasLogicalType, Serializable {
 
     private static final long serialVersionUID = 1L;
 
@@ -178,8 +180,8 @@ final class ObjectMementoWkt implements Serializable {
                     ObjectMementoWkt memento,
                     MetaModelContext mmc) {
 
-                ObjectSpecId specId = memento.objectSpecId;
-                ObjectSpecification objectSpec = mmc.getSpecificationLoader().lookupBySpecIdElseLoad(specId);
+                ObjectSpecification objectSpec = mmc.getSpecificationLoader()
+                        .lookupBySpecIdElseLoad(memento.logicalType);
                 EncodableFacet encodableFacet = objectSpec.getFacet(EncodableFacet.class);
                 return encodableFacet.fromEncodedString(memento.encodableValue);
             }
@@ -220,7 +222,8 @@ final class ObjectMementoWkt implements Serializable {
                     MetaModelContext mmc) {
 
                 if(_NullSafe.isEmpty(memento.persistentOidStr)) {
-                    throw _Exceptions.illegalArgument("need an id to lookup an object specId=%s", memento.objectSpecId);
+                    throw _Exceptions.illegalArgument(
+                            "need an id to lookup an object, got logical-type %s", memento.logicalType);
                 }
 
                 RootOid rootOid = Oid.unmarshaller().unmarshal(memento.persistentOidStr, RootOid.class);
@@ -277,9 +280,8 @@ final class ObjectMementoWkt implements Serializable {
             public ManagedObject recreateObject(
                     ObjectMementoWkt memento,
                     MetaModelContext mmc) {
-
-                ObjectSpecId specId = memento.objectSpecId;
-                ObjectSpecification spec = mmc.getSpecificationLoader().lookupBySpecIdElseLoad(specId);
+                ObjectSpecification spec = mmc.getSpecificationLoader()
+                        .lookupBySpecIdElseLoad(memento.logicalType);
                 return mmc.getObjectManager().getObjectSerializer()
                         .deserialize(spec, memento.serializedObject);
             }
@@ -289,7 +291,7 @@ final class ObjectMementoWkt implements Serializable {
                     ObjectMementoWkt memento,
                     ObjectMementoWkt otherMemento) {
                 return otherMemento.recreateStrategy == SERIALIZABLE
-                        && Objects.equals(memento.objectSpecId, otherMemento.objectSpecId)
+                        && Objects.equals(memento.logicalType, otherMemento.logicalType)
                         && Objects.equals(memento.serializedObject, otherMemento.serializedObject);
             }
 
@@ -300,7 +302,7 @@ final class ObjectMementoWkt implements Serializable {
 
             @Override
             public String toString(ObjectMementoWkt memento) {
-                return "ObjectMementoWkt {SERIALIZABLE " + memento.objectSpecId + "}";
+                return "ObjectMementoWkt {SERIALIZABLE " + memento.getLogicalTypeName() + "}";
             }
 
             @Override
@@ -331,7 +333,7 @@ final class ObjectMementoWkt implements Serializable {
 
 
     private final Cardinality cardinality;
-    private final ObjectSpecId objectSpecId;
+    @Getter(onMethod_ = {@Override}) private final LogicalType logicalType;
 
     /**
      * Populated only if {@link #getCardinality() sort} is {@link Cardinality#SCALAR scalar}
@@ -388,48 +390,48 @@ final class ObjectMementoWkt implements Serializable {
 
     private ObjectMementoWkt(
             ArrayList<ObjectMementoWkt> list,
-            ObjectSpecId objectSpecId) {
+            LogicalType logicalType) {
 
         this.cardinality = Cardinality.VECTOR;
         this.list = list;
-        this.objectSpecId = objectSpecId;
+        this.logicalType = logicalType;
     }
 
     private ObjectMementoWkt(RootOid rootOid, SpecificationLoader specificationLoader) {
 
         // -- // TODO[2112] do we ever need to create ENCODEABLE here?
-        val specId = rootOid.getObjectSpecId();
-        val spec = specificationLoader.lookupBySpecIdElseLoad(specId);
-        if(spec!=null && spec.isEncodeable()) {
-            this.cardinality = Cardinality.SCALAR;
-            this.objectSpecId = specId;
+        val logicalTypeName = rootOid.getLogicalTypeName();
+        val spec = specificationLoader.lookupBySpecIdElseLoad(logicalTypeName);
+        if(spec==null) {
+            throw _Exceptions.unrecoverableFormatted("cannot recreate spec from logicalTypeName %s", logicalTypeName);
+        }
+        
+        this.cardinality = Cardinality.SCALAR;
+        this.logicalType = spec.getLogicalType();
+        
+        if(spec.isEncodeable()) {
             this.encodableValue = rootOid.getIdentifier();
             this.recreateStrategy = RecreateStrategy.ENCODEABLE;
             return;
         }
-        // -- //
-
-        this.cardinality = Cardinality.SCALAR;
 
         this.persistentOidStr = rootOid.enString();
-
         requires(persistentOidStr, "persistentOidStr");
 
         this.bookmark = rootOid.asBookmark();
-        this.objectSpecId = rootOid.getObjectSpecId();
         this.recreateStrategy = RecreateStrategy.LOOKUP;
     }
 
     private ObjectMementoWkt(@NonNull final ManagedObject adapter) {
         this.cardinality = Cardinality.SCALAR;
         val spec = adapter.getSpecification();
-        objectSpecId = spec.getSpecId();
+        this.logicalType = spec.getLogicalType();
         init(adapter);
     }
 
-    private ObjectMementoWkt(ObjectSpecId specId, String encodableValue) {
+    private ObjectMementoWkt(LogicalType logicalType, String encodableValue) {
         this.cardinality = Cardinality.SCALAR;
-        this.objectSpecId = specId;
+        this.logicalType = logicalType;
         this.encodableValue = encodableValue;
         this.recreateStrategy = RecreateStrategy.ENCODEABLE;
     }
@@ -488,7 +490,7 @@ final class ObjectMementoWkt implements Serializable {
         val bookmark = asBookmark();
         return hintId != null && bookmark != null
                 ? bookmark.withHintId(hintId)
-                        : bookmark;
+                : bookmark;
     }
 
     /**
@@ -504,7 +506,7 @@ final class ObjectMementoWkt implements Serializable {
     ManagedObject reconstructObject(MetaModelContext mmc) {
 
         val specificationLoader = mmc.getSpecificationLoader();
-        val spec = specificationLoader.loadSpecification(objectSpecId);
+        val spec = specificationLoader.lookupBySpecIdElseLoad(logicalType);
         if(spec==null) {
             // eg. ill-formed request
             return null;
@@ -512,16 +514,12 @@ final class ObjectMementoWkt implements Serializable {
 
         // intercept when managed by IoCC
         if(spec.getBeanSort().isManagedBean()) {
-            return spec.getMetaModelContext().lookupServiceAdapterById(objectSpecId.asString());
+            return spec.getMetaModelContext().lookupServiceAdapterById(getLogicalTypeName());
         }
 
         return cardinality.asAdapter(this, mmc);
     }
 
-    ObjectSpecId getObjectSpecId() {
-        return objectSpecId;
-    }
-
     @Override
     public int hashCode() {
         return cardinality.hashCode(this);


[isis] 07/11: ISIS-2553: test fixes

Posted by ah...@apache.org.
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

commit a82d59bf77238369f3c676832f8b5cb17eefd064
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Mar 1 20:02:31 2021 +0100

    ISIS-2553: test fixes
---
 .../object/domainobject/DomainObjectAnnotationFacetFactoryTest.java    | 3 +--
 .../object/domainobject/ObjectTypeAnnotationFacetFactoryTest.java      | 3 +--
 .../objectspecid/ObjectSpecIdFacetDerivedFromClassNameFactoryTest.java | 3 +--
 .../discriminator/GivenJdoDiscriminatorAnnotationFacetFactoryTest.java | 3 +--
 4 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
index a2246a7..b83261b 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
@@ -34,7 +34,6 @@ import static org.junit.Assert.assertFalse;
 
 import org.apache.isis.applib.annotation.Bounding;
 import org.apache.isis.applib.annotation.DomainObject;
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.commons.having.HasUniqueId;
 import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.core.config.metamodel.facets.EditingObjectsConfiguration;
@@ -560,7 +559,7 @@ public class DomainObjectAnnotationFacetFactoryTest extends AbstractFacetFactory
             final ObjectSpecIdFacetForDomainObjectAnnotation facetForDomainObjectAnnotation =
                     (ObjectSpecIdFacetForDomainObjectAnnotation) facet;
 
-            assertThat(facetForDomainObjectAnnotation.value(), is(ObjectSpecId.of("CUS")));
+            assertThat(facetForDomainObjectAnnotation.value(), is("CUS"));
 
             expectNoMethodsRemoved();
         }
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectTypeAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectTypeAnnotationFacetFactoryTest.java
index 8c6a3b6..3b50a6c 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectTypeAnnotationFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/ObjectTypeAnnotationFacetFactoryTest.java
@@ -28,7 +28,6 @@ import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import org.apache.isis.applib.annotation.DomainObject;
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryJUnit4TestCase;
 import org.apache.isis.core.metamodel.facets.ObjectSpecIdFacetFactory.ProcessObjectSpecIdContext;
 import org.apache.isis.core.metamodel.facets.object.domainobject.objectspecid.ObjectSpecIdFacetForDomainObjectAnnotation;
@@ -58,7 +57,7 @@ public class ObjectTypeAnnotationFacetFactoryTest extends AbstractFacetFactoryJU
 
         assertThat(facet, is(not(nullValue())));
         assertThat(facet instanceof ObjectSpecIdFacetForDomainObjectAnnotation, is(true));
-        assertThat(facet.value(), is(ObjectSpecId.of("CUS")));
+        assertThat(facet.value(), is("CUS"));
 
     }
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetDerivedFromClassNameFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetDerivedFromClassNameFactoryTest.java
index 1445001..751f834 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetDerivedFromClassNameFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectSpecIdFacetDerivedFromClassNameFactoryTest.java
@@ -28,7 +28,6 @@ import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryJUnit4TestCase;
 import org.apache.isis.core.metamodel.facets.ObjectSpecIdFacetFactory;
 import org.apache.isis.core.metamodel.facets.object.objectspecid.classname.ObjectSpecIdFacetDerivedFromClassName;
@@ -56,7 +55,7 @@ public class ObjectSpecIdFacetDerivedFromClassNameFactoryTest extends AbstractFa
 
         assertThat(facet, is(not(nullValue())));
         assertThat(facet instanceof ObjectSpecIdFacetDerivedFromClassName, is(true));
-        assertThat(facet.value(), is(ObjectSpecId.of(Customer.class.getCanonicalName())));
+        assertThat(facet.value(), is(Customer.class.getCanonicalName()));
     }
 
 }
diff --git a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/discriminator/GivenJdoDiscriminatorAnnotationFacetFactoryTest.java b/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/discriminator/GivenJdoDiscriminatorAnnotationFacetFactoryTest.java
index f2dd166..4dd4fbd 100644
--- a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/discriminator/GivenJdoDiscriminatorAnnotationFacetFactoryTest.java
+++ b/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/discriminator/GivenJdoDiscriminatorAnnotationFacetFactoryTest.java
@@ -21,7 +21,6 @@ package org.apache.isis.persistence.jdo.metamodel.facets.object.discriminator;
 import javax.jdo.annotations.Discriminator;
 import javax.jdo.annotations.PersistenceCapable;
 
-import org.apache.isis.applib.id.ObjectSpecId;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.FacetFactory;
@@ -102,7 +101,7 @@ public class GivenJdoDiscriminatorAnnotationFacetFactoryTest extends AbstractFac
         facetFactory.process(new ObjectSpecIdFacetFactory.ProcessObjectSpecIdContext(Customer.class, facetHolder));
 
         final ObjectSpecIdFacet discriminatorValueFacet = facetHolder.getFacet(ObjectSpecIdFacet.class);
-        assertEquals(ObjectSpecId.of("CUS"), discriminatorValueFacet.value());
+        assertEquals("CUS", discriminatorValueFacet.value());
     }
 
     public void testNoMethodsRemoved() {


[isis] 11/11: ISIS-2553: prepare for merge

Posted by ah...@apache.org.
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

commit 20c99faecf2561290b08b22bf6caf698b5afdeac
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Mar 2 08:15:51 2021 +0100

    ISIS-2553: prepare for merge
---
 .../isis/core/metamodel/services/appfeat/ApplicationFeatureId.java       | 1 -
 1 file changed, 1 deletion(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
index 5197607..f6ce177 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureId.java
@@ -52,7 +52,6 @@ import lombok.val;
  * {@link #getType() (feature) type}, {@link #getNamespace() logical package name}, 
  * {@link #getTypeSimpleName() class name} and {@link #getMemberName() member name}.
  * 
- * @deprecated use {@link Identifier} instead  
  */
 @Value
 public class ApplicationFeatureId