This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 8bc96a1d81 ISIS-3167: refactor ManagedObject nested types into their
own files
8bc96a1d81 is described below
commit 8bc96a1d812d671a930540594bae13ec1da29b8e
Author: Andi Huber <[email protected]>
AuthorDate: Sat Aug 27 15:05:09 2022 +0200
ISIS-3167: refactor ManagedObject nested types into their own files
---
.../isis/core/metamodel/object/ManagedObject.java | 284 +--------------------
.../isis/core/metamodel/object/ManagedObjects.java | 42 +--
.../core/metamodel/object/PackedManagedObject.java | 64 +----
.../metamodel/object/_ManagedObjectAbstract.java | 62 +++++
...anagedObject.java => _ManagedObjectPacked.java} | 12 +-
...dObject.java => _ManagedObjectUnspecified.java} | 44 +---
.../object/_ManagedObjectWithBookmark.java | 170 ++++++++++++
.../object/_ManagedObjectWithEagerSpec.java | 71 ++++++
.../object/_ManagedObjectWithLazySpec.java | 77 ++++++
.../core/metamodel/spec/feature/ObjectAction.java | 4 +-
.../core/metamodel/util/snapshot/XmlSnapshot.java | 2 +-
.../domainobjects/ObjectActionReprRenderer.java | 4 +-
.../domainobjects/ObjectAndActionInvocation.java | 4 +-
.../resources/ObjectAdapterUpdateHelper.java | 4 +-
.../entity/icontitle/EntityIconAndTitlePanel.java | 5 +-
15 files changed, 421 insertions(+), 428 deletions(-)
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java
index 15b49dd0d9..ed7e9a26cf 100644
---
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java
@@ -18,10 +18,7 @@
*/
package org.apache.isis.core.metamodel.object;
-import java.util.Objects;
import java.util.Optional;
-import java.util.UUID;
-import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
@@ -30,25 +27,16 @@ import org.springframework.lang.Nullable;
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.applib.value.semantics.Renderer;
import org.apache.isis.commons.internal.assertions._Assert;
-import org.apache.isis.commons.internal.base._Lazy;
import org.apache.isis.commons.internal.collections._Collections;
-import org.apache.isis.commons.internal.debug._XrayEvent;
import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.core.metamodel.context.MetaModelContext;
+import org.apache.isis.core.metamodel.context.HasMetaModelContext;
import org.apache.isis.core.metamodel.facets.object.icon.ObjectIcon;
import org.apache.isis.core.metamodel.facets.object.title.TitleRenderRequest;
-import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
-import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
-import lombok.AccessLevel;
-import lombok.AllArgsConstructor;
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
import lombok.NonNull;
-import lombok.ToString;
import lombok.val;
/**
@@ -56,7 +44,7 @@ import lombok.val;
* that is IoC-container provided beans, persistence-stack provided entities
or view-models.
*
*/
-public interface ManagedObject {
+public interface ManagedObject extends HasMetaModelContext {
/**
* Returns the specification that details the structure (meta-model) of
this object.
@@ -94,24 +82,10 @@ public interface ManagedObject {
boolean isBookmarkMemoized();
- default Supplier<ManagedObject> asProvider() {
- return ()->this;
- }
+ Supplier<ManagedObject> asSupplier();
- /** debug */
- default void assertSpecIsInSyncWithPojo() {
-// val pojo = getPojo();
-// val spec = getSpecification();
-// if(pojo==null
-// || spec==null) {
-// return;
-// }
-// val actualSpec =
spec.getSpecificationLoader().specForType(pojo.getClass()).orElse(null);
-// if(!Objects.equals(spec, actualSpec)) {
-// System.err.printf("spec mismatch %s %s%n", spec, actualSpec);
-// }
- //_Assert.assertEquals(spec, actualSpec);
- }
+ @Deprecated
+ void assertSpecIsInSyncWithPojo();
// -- HTML
@@ -155,20 +129,6 @@ public interface ManagedObject {
.build());
}
- // -- SHORTCUTS - MM CONTEXT
-
- default MetaModelContext getMetaModelContext() {
- return ManagedObjects.spec(this)
- .map(ObjectSpecification::getMetaModelContext)
- .orElseThrow(()->_Exceptions
- .illegalArgument("Can only retrieve MetaModelContext
from ManagedObjects "
- + "that have an ObjectSpecification."));
- }
-
- default ObjectManager getObjectManager() {
- return getMetaModelContext().getObjectManager();
- }
-
// -- SHORTCUT - ELEMENT SPECIFICATION
/**
@@ -205,7 +165,7 @@ public interface ManagedObject {
public static ManagedObject notBookmarked(
final ObjectSpecification spec,
final Object pojo) {
- return SimpleManagedObject.of(spec, pojo);
+ return _ManagedObjectWithEagerSpec.of(spec, pojo);
}
/**
@@ -248,7 +208,7 @@ public interface ManagedObject {
spec.getCorrespondingClass(), pojo.getClass(),
pojo.toString());
}
ManagedObjects.assertPojoNotWrapped(pojo);
- return SimpleManagedObject.identified(spec, pojo, bookmark);
+ return _ManagedObjectWithEagerSpec.identified(spec, pojo, bookmark);
}
/**
@@ -265,243 +225,19 @@ public interface ManagedObject {
}
ManagedObjects.assertPojoNotWrapped(pojo);
- val adapter = new
LazyManagedObject(cls->specLoader.specForType(cls).orElse(null), pojo);
+ val adapter = new
_ManagedObjectWithLazySpec(cls->specLoader.specForType(cls).orElse(null), pojo);
//ManagedObjects.warnIfAttachedEntity(adapter, "consider using
ManagedObject.identified(...) for entity");
return adapter;
}
- // -- EMPTY
-
/** has no ObjectSpecification and no value (pojo) */
static ManagedObject unspecified() {
- return ManagedObjects.UNSPECIFIED;
+ return _ManagedObjectAbstract.UNSPECIFIED;
}
/** has an ObjectSpecification, but no value (pojo) */
static ManagedObject empty(final @NonNull ObjectSpecification spec) {
- return SimpleManagedObject.of(spec, null);
- }
-
- // -- LAZY BOOKMARK HANDLING
-
- static abstract class ManagedObjectWithBookmark
- implements ManagedObject {
-
- protected final _Lazy<Optional<Bookmark>> bookmarkLazy =
- _Lazy.threadSafe(()->bookmark(this));
-
- @Override
- public final Optional<Bookmark> getBookmark() {
- return bookmarkLazy.get();
- }
-
- @Override
- public final boolean isBookmarkMemoized() {
- return bookmarkLazy.isMemoized();
- }
-
- @Override
- public final Optional<Bookmark> getBookmarkRefreshed() {
- // silently ignore invalidation, when the pojo is an entity
- if(!getSpecification().isEntity()) {
- bookmarkLazy.clear();
- }
- return getBookmark();
- }
-
- private void replaceBookmark(final UnaryOperator<Bookmark> replacer) {
- final Bookmark old = bookmarkLazy.isMemoized()
- ? bookmarkLazy.get().orElse(null)
- : null;
- bookmarkLazy.clear();
- bookmarkLazy.set(Optional.ofNullable(replacer.apply(old)));
- }
-
- // guards against non-identifiable objects;
- // historically, we allowed non-identifiable to be handled by the
objectManager,
- // which as a fallback creates 'random' UUIDs
- private Optional<Bookmark> bookmark(final @Nullable ManagedObject
adapter) {
-
- if(ManagedObjects.isNullOrUnspecifiedOrEmpty(adapter)
- || adapter.getSpecification().isValue()
- || !ManagedObjects.isIdentifiable(adapter)) {
- return Optional.empty();
- }
-
- return ManagedObjects.spec(adapter)
- .map(ObjectSpecification::getMetaModelContext)
- .map(MetaModelContext::getObjectManager)
- .map(objectManager->objectManager.bookmarkObject(adapter));
- }
-
- // -- REFRESH OPTIMIZATION
-
- private UUID interactionIdDuringWhichRefreshed = null;
-
- @Override
- public final void refreshViewmodel(final @Nullable Supplier<Bookmark>
bookmarkSupplier) {
- val spec = getSpecification();
- if(spec.isViewModel()) {
- val viewModelFacet = spec.getFacet(ViewModelFacet.class);
- if(viewModelFacet.containsEntities()) {
-
- val shouldRefresh =
spec.getMetaModelContext().getInteractionProvider().getInteractionId()
- .map(this::shouldRefresh)
- .orElse(true); // if there is no current interaction,
refresh regardless; unexpected state, might fail later
-
- if(!shouldRefresh) {
- return;
- }
-
- if(isBookmarkMemoized()) {
- reloadViewmodelFromMemoizedBookmark();
- } else {
- val bookmark = bookmarkSupplier!=null
- ? bookmarkSupplier.get()
- : null;
- if(bookmark!=null) {
- reloadViewmodelFromBookmark(bookmark);
- }
- }
- }
- }
- }
-
- private boolean shouldRefresh(final @NonNull UUID interactionId) {
- if(Objects.equals(this.interactionIdDuringWhichRefreshed,
interactionId)) {
- return false; // already refreshed within current interaction
- }
- this.interactionIdDuringWhichRefreshed = interactionId;
- return true;
- }
-
- /**
- * Reload current viewmodel object from memoized bookmark, otherwise
does nothing.
- */
- private void reloadViewmodelFromMemoizedBookmark() {
- val spec = getSpecification();
- if(isBookmarkMemoized()
- && spec.isViewModel()) {
-
- val bookmark = getBookmark().get();
- val viewModelClass = spec.getCorrespondingClass();
-
- val recreatedViewmodel =
-
getMetaModelContext().getFactoryService().viewModel(viewModelClass, bookmark);
-
- _XrayEvent.event("Viewmodel '%s' recreated from memoized
bookmark.", viewModelClass.getName());
-
- replacePojo(old->recreatedViewmodel);
- }
- }
-
- private void reloadViewmodelFromBookmark(final @NonNull Bookmark
bookmark) {
- val spec = getSpecification();
- if(spec.isViewModel()) {
- val viewModelClass = spec.getCorrespondingClass();
-
- val recreatedViewmodel =
-
getMetaModelContext().getFactoryService().viewModel(viewModelClass, bookmark);
-
- _XrayEvent.event("Viewmodel '%s' recreated from provided
bookmark.", viewModelClass.getName());
-
- replacePojo(old->recreatedViewmodel);
- replaceBookmark(old->bookmark);
- }
- }
-
- /**
- * Introduced, so we can re-fetch detached entity pojos in place.
- */
- abstract void replacePojo(UnaryOperator<Object> replacer);
-
- }
-
- // -- SIMPLE
-
- //@Value
- //@RequiredArgsConstructor(staticName="of", access = AccessLevel.PRIVATE)
- @AllArgsConstructor(staticName="of", access = AccessLevel.PRIVATE)
- @EqualsAndHashCode(of = "pojo", callSuper = false)
- @ToString(of = {"specification", "pojo"}) //ISIS-2317 make sure toString()
is without side-effects
- @Getter
- static final class SimpleManagedObject
- extends ManagedObjectWithBookmark {
-
- public static ManagedObject identified(
- final @NonNull ObjectSpecification spec,
- final @Nullable Object pojo,
- final @NonNull Bookmark bookmark) {
-
- if(pojo!=null) {
-
_Assert.assertFalse(_Collections.isCollectionOrArrayOrCanType(pojo.getClass()));
- }
-
- val managedObject = SimpleManagedObject.of(spec, pojo);
- managedObject.bookmarkLazy.set(Optional.of(bookmark));
- return managedObject;
- }
-
- @NonNull private final ObjectSpecification specification;
- @Nullable private /*final*/ Object pojo;
-
- @Override
- public void replacePojo(final UnaryOperator<Object> replacer) {
- pojo = replacer.apply(pojo);
- assertSpecIsInSyncWithPojo();
- }
-
- }
-
- // -- LAZY
-
- @EqualsAndHashCode(of = "pojo", callSuper = false)
- static final class LazyManagedObject
- extends ManagedObjectWithBookmark {
-
- @NonNull private final Function<Class<?>, ObjectSpecification>
specLoader;
-
- @Getter @NonNull private /*final*/ Object pojo;
-
- private final _Lazy<ObjectSpecification> specification =
_Lazy.threadSafe(this::loadSpec);
-
- public LazyManagedObject(
- final @NonNull Function<Class<?>, ObjectSpecification>
specLoader,
- final @NonNull Object pojo) {
- this.specLoader = specLoader;
- this.pojo = pojo;
- }
-
- @Override
- public ObjectSpecification getSpecification() {
- return specification.get();
- }
-
- @Override //ISIS-2317 make sure toString() is without side-effects
- public String toString() {
- if(specification.isMemoized()) {
- return String.format("ManagedObject[spec=%s, pojo=%s]",
- ""+getSpecification(),
- ""+getPojo());
- }
- return String.format("ManagedObject[spec=%s, pojo=%s]",
- "[lazy not loaded]",
- ""+getPojo());
- }
-
- private ObjectSpecification loadSpec() {
- return specLoader.apply(pojo.getClass());
- }
-
- @Override
- public void replacePojo(final UnaryOperator<Object> replacer) {
- pojo = replacer.apply(pojo);
- if(specification.isMemoized()) {
- assertSpecIsInSyncWithPojo();
- }
- }
-
+ return _ManagedObjectWithEagerSpec.of(spec, null);
}
-
}
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java
index 7729f7593f..d98f698b5a 100644
---
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java
@@ -62,7 +62,6 @@ import
org.apache.isis.core.metamodel.interactions.InteractionHead;
import org.apache.isis.core.metamodel.interactions.InteractionUtils;
import org.apache.isis.core.metamodel.interactions.ObjectVisibilityContext;
import org.apache.isis.core.metamodel.interactions.VisibilityContext;
-import
org.apache.isis.core.metamodel.object.ManagedObject.ManagedObjectWithBookmark;
import org.apache.isis.core.metamodel.objectmanager.load.ObjectLoader;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
@@ -151,6 +150,10 @@ public final class ManagedObjects {
// -- INSTANCE-OF CHECKS
+ public static boolean isPacked(final @Nullable ManagedObject
managedObject) {
+ return managedObject instanceof PackedManagedObject;
+ }
+
/**
* Whether given {@code object} is an instance of given {@code
elementType}.
*/
@@ -499,41 +502,6 @@ public final class ManagedObjects {
return result;
}
- // -- UNSPECIFIED OBJECT
-
- static final ManagedObject UNSPECIFIED = new ManagedObject() {
-
- @Override
- public ObjectSpecification getSpecification() {
- throw _Exceptions.unsupportedOperation();
- }
-
- @Override
- public Object getPojo() {
- return null;
- }
-
- @Override
- public Optional<Bookmark> getBookmark() {
- return Optional.empty();
- }
-
- @Override
- public Optional<Bookmark> getBookmarkRefreshed() {
- return Optional.empty();
- }
-
- @Override
- public boolean isBookmarkMemoized() {
- return false;
- }
-
- @Override
- public void refreshViewmodel(final @Nullable Supplier<Bookmark>
bookmarkSupplier) {
- // noop; only available for viewmodels
- }
- };
-
// -- SPECIFICATION UTILITIES
/**
@@ -770,7 +738,7 @@ public final class ManagedObjects {
val newState = EntityUtil.getEntityState(reattached);
_Assert.assertTrue(newState.isAttached());
- _Casts.castTo(ManagedObjectWithBookmark.class, managedObject)
+ _Casts.castTo(_ManagedObjectWithBookmark.class, managedObject)
.ifPresent(obj->obj.replacePojo(old->reattached.getPojo()));
return managedObject;
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/PackedManagedObject.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/PackedManagedObject.java
index d335b406e0..590c5ab8c0 100644
---
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/PackedManagedObject.java
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/PackedManagedObject.java
@@ -18,74 +18,18 @@
*/
package org.apache.isis.core.metamodel.object;
-import java.util.Collections;
-import java.util.Optional;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
-import org.springframework.lang.Nullable;
-
-import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.internal.base._Lazy;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import lombok.RequiredArgsConstructor;
-import lombok.ToString;
-
-@RequiredArgsConstructor
-@ToString
-public final class PackedManagedObject implements ManagedObject {
-
- final ObjectSpecification elementSpec;
- final Can<ManagedObject> nonScalar;
+public interface PackedManagedObject
+extends ManagedObject {
public static ManagedObject pack(
final ObjectSpecification elementSpec,
final Can<ManagedObject> nonScalar) {
- return new PackedManagedObject(elementSpec, nonScalar);
- }
-
- @Override
- public ObjectSpecification getSpecification() {
- return elementSpec;
- }
-
- @Override
- public Object getPojo() {
- return Collections.unmodifiableList(
- nonScalar.stream()
- .map(ManagedObject::getPojo)
- .collect(Collectors.toList()));
- }
-
- private final _Lazy<Optional<Bookmark>> bookmarkLazy =
- _Lazy.threadSafe(()->{
- return
Optional.of(getSpecification().getMetaModelContext().getObjectManager().bookmarkObject(this));
- });
-
- @Override
- public Optional<Bookmark> getBookmark() {
- return bookmarkLazy.get();
+ return new _ManagedObjectPacked(elementSpec, nonScalar);
}
- @Override
- public Optional<Bookmark> getBookmarkRefreshed() {
- return getBookmark(); // no-effect
- }
-
- @Override
- public boolean isBookmarkMemoized() {
- return bookmarkLazy.isMemoized();
- }
-
- public Can<ManagedObject> unpack(){
- return nonScalar;
- }
-
- @Override
- public void refreshViewmodel(final @Nullable Supplier<Bookmark>
bookmarkSupplier) {
- // noop; only available for viewmodels
- }
+ Can<ManagedObject> unpack();
}
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectAbstract.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectAbstract.java
new file mode 100644
index 0000000000..f6cd5842d1
--- /dev/null
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectAbstract.java
@@ -0,0 +1,62 @@
+/*
+ * 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.object;
+
+import java.util.function.Supplier;
+
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.core.metamodel.context.MetaModelContext;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+abstract class _ManagedObjectAbstract
+implements ManagedObject {
+
+ static final ManagedObject UNSPECIFIED = new _ManagedObjectUnspecified();
+
+ @Override
+ public final MetaModelContext getMetaModelContext() {
+ return ManagedObjects.spec(this)
+ .map(ObjectSpecification::getMetaModelContext)
+ .orElseThrow(()->_Exceptions
+ .illegalArgument("Can only retrieve MetaModelContext
from ManagedObjects "
+ + "that have an ObjectSpecification."));
+ }
+
+ @Override
+ public final Supplier<ManagedObject> asSupplier() {
+ return ()->this;
+ }
+
+ /** debug */
+ @Override
+ public void assertSpecIsInSyncWithPojo() {
+// val pojo = getPojo();
+// val spec = getSpecification();
+// if(pojo==null
+// || spec==null) {
+// return;
+// }
+// val actualSpec =
spec.getSpecificationLoader().specForType(pojo.getClass()).orElse(null);
+// if(!Objects.equals(spec, actualSpec)) {
+// System.err.printf("spec mismatch %s %s%n", spec, actualSpec);
+// }
+ //_Assert.assertEquals(spec, actualSpec);
+ }
+
+}
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/PackedManagedObject.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectPacked.java
similarity index 88%
copy from
core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/PackedManagedObject.java
copy to
core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectPacked.java
index d335b406e0..8bba1b6e56 100644
---
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/PackedManagedObject.java
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectPacked.java
@@ -35,17 +35,13 @@ import lombok.ToString;
@RequiredArgsConstructor
@ToString
-public final class PackedManagedObject implements ManagedObject {
+final class _ManagedObjectPacked
+extends _ManagedObjectAbstract
+implements PackedManagedObject {
final ObjectSpecification elementSpec;
final Can<ManagedObject> nonScalar;
- public static ManagedObject pack(
- final ObjectSpecification elementSpec,
- final Can<ManagedObject> nonScalar) {
- return new PackedManagedObject(elementSpec, nonScalar);
- }
-
@Override
public ObjectSpecification getSpecification() {
return elementSpec;
@@ -79,13 +75,13 @@ public final class PackedManagedObject implements
ManagedObject {
return bookmarkLazy.isMemoized();
}
+ @Override
public Can<ManagedObject> unpack(){
return nonScalar;
}
@Override
public void refreshViewmodel(final @Nullable Supplier<Bookmark>
bookmarkSupplier) {
- // noop; only available for viewmodels
}
}
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/PackedManagedObject.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectUnspecified.java
similarity index 54%
copy from
core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/PackedManagedObject.java
copy to
core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectUnspecified.java
index d335b406e0..d74e9f5cbf 100644
---
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/PackedManagedObject.java
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectUnspecified.java
@@ -18,74 +18,44 @@
*/
package org.apache.isis.core.metamodel.object;
-import java.util.Collections;
import java.util.Optional;
import java.util.function.Supplier;
-import java.util.stream.Collectors;
import org.springframework.lang.Nullable;
import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.internal.base._Lazy;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import lombok.RequiredArgsConstructor;
-import lombok.ToString;
-
-@RequiredArgsConstructor
-@ToString
-public final class PackedManagedObject implements ManagedObject {
-
- final ObjectSpecification elementSpec;
- final Can<ManagedObject> nonScalar;
-
- public static ManagedObject pack(
- final ObjectSpecification elementSpec,
- final Can<ManagedObject> nonScalar) {
- return new PackedManagedObject(elementSpec, nonScalar);
- }
+final class _ManagedObjectUnspecified extends _ManagedObjectAbstract {
@Override
public ObjectSpecification getSpecification() {
- return elementSpec;
+ throw _Exceptions.unsupportedOperation();
}
@Override
public Object getPojo() {
- return Collections.unmodifiableList(
- nonScalar.stream()
- .map(ManagedObject::getPojo)
- .collect(Collectors.toList()));
+ return null;
}
- private final _Lazy<Optional<Bookmark>> bookmarkLazy =
- _Lazy.threadSafe(()->{
- return
Optional.of(getSpecification().getMetaModelContext().getObjectManager().bookmarkObject(this));
- });
-
@Override
public Optional<Bookmark> getBookmark() {
- return bookmarkLazy.get();
+ return Optional.empty();
}
@Override
public Optional<Bookmark> getBookmarkRefreshed() {
- return getBookmark(); // no-effect
+ return Optional.empty();
}
@Override
public boolean isBookmarkMemoized() {
- return bookmarkLazy.isMemoized();
- }
-
- public Can<ManagedObject> unpack(){
- return nonScalar;
+ return false;
}
@Override
public void refreshViewmodel(final @Nullable Supplier<Bookmark>
bookmarkSupplier) {
- // noop; only available for viewmodels
}
}
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithBookmark.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithBookmark.java
new file mode 100644
index 0000000000..50e0ddd12f
--- /dev/null
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithBookmark.java
@@ -0,0 +1,170 @@
+/*
+ * 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.object;
+
+import java.util.Objects;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+
+import org.springframework.lang.Nullable;
+
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.commons.internal.base._Lazy;
+import org.apache.isis.commons.internal.debug._XrayEvent;
+import org.apache.isis.core.metamodel.context.MetaModelContext;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+import lombok.NonNull;
+import lombok.val;
+
+abstract class _ManagedObjectWithBookmark
+extends _ManagedObjectAbstract {
+
+ protected final _Lazy<Optional<Bookmark>> bookmarkLazy =
+ _Lazy.threadSafe(()->bookmark(this));
+
+ @Override
+ public final Optional<Bookmark> getBookmark() {
+ return bookmarkLazy.get();
+ }
+
+ @Override
+ public final boolean isBookmarkMemoized() {
+ return bookmarkLazy.isMemoized();
+ }
+
+ @Override
+ public final Optional<Bookmark> getBookmarkRefreshed() {
+ // silently ignore invalidation, when the pojo is an entity
+ if(!getSpecification().isEntity()) {
+ bookmarkLazy.clear();
+ }
+ return getBookmark();
+ }
+
+ private void replaceBookmark(final UnaryOperator<Bookmark> replacer) {
+ final Bookmark old = bookmarkLazy.isMemoized()
+ ? bookmarkLazy.get().orElse(null)
+ : null;
+ bookmarkLazy.clear();
+ bookmarkLazy.set(Optional.ofNullable(replacer.apply(old)));
+ }
+
+ // guards against non-identifiable objects;
+ // historically, we allowed non-identifiable to be handled by the
objectManager,
+ // which as a fallback creates 'random' UUIDs
+ private Optional<Bookmark> bookmark(final @Nullable ManagedObject adapter)
{
+
+ if(ManagedObjects.isNullOrUnspecifiedOrEmpty(adapter)
+ || adapter.getSpecification().isValue()
+ || !ManagedObjects.isIdentifiable(adapter)) {
+ return Optional.empty();
+ }
+
+ return ManagedObjects.spec(adapter)
+ .map(ObjectSpecification::getMetaModelContext)
+ .map(MetaModelContext::getObjectManager)
+ .map(objectManager->objectManager.bookmarkObject(adapter));
+ }
+
+ // -- REFRESH OPTIMIZATION
+
+ private UUID interactionIdDuringWhichRefreshed = null;
+
+ @Override
+ public final void refreshViewmodel(final @Nullable Supplier<Bookmark>
bookmarkSupplier) {
+ val spec = getSpecification();
+ if(spec.isViewModel()) {
+ val viewModelFacet = spec.getFacet(ViewModelFacet.class);
+ if(viewModelFacet.containsEntities()) {
+
+ val shouldRefresh =
spec.getMetaModelContext().getInteractionProvider().getInteractionId()
+ .map(this::shouldRefresh)
+ .orElse(true); // if there is no current interaction, refresh
regardless; unexpected state, might fail later
+
+ if(!shouldRefresh) {
+ return;
+ }
+
+ if(isBookmarkMemoized()) {
+ reloadViewmodelFromMemoizedBookmark();
+ } else {
+ val bookmark = bookmarkSupplier!=null
+ ? bookmarkSupplier.get()
+ : null;
+ if(bookmark!=null) {
+ reloadViewmodelFromBookmark(bookmark);
+ }
+ }
+ }
+ }
+ }
+
+ private boolean shouldRefresh(final @NonNull UUID interactionId) {
+ if(Objects.equals(this.interactionIdDuringWhichRefreshed,
interactionId)) {
+ return false; // already refreshed within current interaction
+ }
+ this.interactionIdDuringWhichRefreshed = interactionId;
+ return true;
+ }
+
+ /**
+ * Reload current viewmodel object from memoized bookmark, otherwise does
nothing.
+ */
+ private void reloadViewmodelFromMemoizedBookmark() {
+ val spec = getSpecification();
+ if(isBookmarkMemoized()
+ && spec.isViewModel()) {
+
+ val bookmark = getBookmark().get();
+ val viewModelClass = spec.getCorrespondingClass();
+
+ val recreatedViewmodel =
+
getMetaModelContext().getFactoryService().viewModel(viewModelClass, bookmark);
+
+ _XrayEvent.event("Viewmodel '%s' recreated from memoized
bookmark.", viewModelClass.getName());
+
+ replacePojo(old->recreatedViewmodel);
+ }
+ }
+
+ private void reloadViewmodelFromBookmark(final @NonNull Bookmark bookmark)
{
+ val spec = getSpecification();
+ if(spec.isViewModel()) {
+ val viewModelClass = spec.getCorrespondingClass();
+
+ val recreatedViewmodel =
+
getMetaModelContext().getFactoryService().viewModel(viewModelClass, bookmark);
+
+ _XrayEvent.event("Viewmodel '%s' recreated from provided
bookmark.", viewModelClass.getName());
+
+ replacePojo(old->recreatedViewmodel);
+ replaceBookmark(old->bookmark);
+ }
+ }
+
+ /**
+ * Introduced, so we can re-fetch detached entity pojos in place.
+ */
+ abstract void replacePojo(UnaryOperator<Object> replacer);
+
+}
\ No newline at end of file
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithEagerSpec.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithEagerSpec.java
new file mode 100644
index 0000000000..923b4ecb92
--- /dev/null
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithEagerSpec.java
@@ -0,0 +1,71 @@
+/*
+ * 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.object;
+
+import java.util.Optional;
+import java.util.function.UnaryOperator;
+
+import org.springframework.lang.Nullable;
+
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.commons.internal.assertions._Assert;
+import org.apache.isis.commons.internal.collections._Collections;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.ToString;
+import lombok.val;
+
+//@Value
+//@RequiredArgsConstructor(staticName="of", access = AccessLevel.PRIVATE)
+@AllArgsConstructor(staticName="of", access = AccessLevel.PACKAGE)
+@EqualsAndHashCode(of = "pojo", callSuper = false)
+@ToString(of = {"specification", "pojo"}) //ISIS-2317 make sure toString() is
without side-effects
+@Getter
+final class _ManagedObjectWithEagerSpec
+extends _ManagedObjectWithBookmark {
+
+ public static ManagedObject identified(
+ final @NonNull ObjectSpecification spec,
+ final @Nullable Object pojo,
+ final @NonNull Bookmark bookmark) {
+
+ if(pojo!=null) {
+
_Assert.assertFalse(_Collections.isCollectionOrArrayOrCanType(pojo.getClass()));
+ }
+
+ val managedObject = _ManagedObjectWithEagerSpec.of(spec, pojo);
+ managedObject.bookmarkLazy.set(Optional.of(bookmark));
+ return managedObject;
+ }
+
+ @NonNull private final ObjectSpecification specification;
+ @Nullable private /*final*/ Object pojo;
+
+ @Override
+ public void replacePojo(final UnaryOperator<Object> replacer) {
+ pojo = replacer.apply(pojo);
+ assertSpecIsInSyncWithPojo();
+ }
+
+}
\ No newline at end of file
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithLazySpec.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithLazySpec.java
new file mode 100644
index 0000000000..14d9d79fd5
--- /dev/null
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithLazySpec.java
@@ -0,0 +1,77 @@
+/*
+ * 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.object;
+
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+import org.apache.isis.commons.internal.base._Lazy;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.NonNull;
+
+@EqualsAndHashCode(of = "pojo", callSuper = false)
+final class _ManagedObjectWithLazySpec
+extends _ManagedObjectWithBookmark {
+
+ @NonNull private final Function<Class<?>, ObjectSpecification> specLoader;
+
+ @Getter @NonNull private /*final*/ Object pojo;
+
+ private final _Lazy<ObjectSpecification> specification =
_Lazy.threadSafe(this::loadSpec);
+
+ public _ManagedObjectWithLazySpec(
+ final @NonNull Function<Class<?>, ObjectSpecification> specLoader,
+ final @NonNull Object pojo) {
+ this.specLoader = specLoader;
+ this.pojo = pojo;
+ }
+
+ @Override
+ public ObjectSpecification getSpecification() {
+ return specification.get();
+ }
+
+ @Override //ISIS-2317 make sure toString() is without side-effects
+ public String toString() {
+ if(specification.isMemoized()) {
+ return String.format("ManagedObject[spec=%s, pojo=%s]",
+ ""+getSpecification(),
+ ""+getPojo());
+ }
+ return String.format("ManagedObject[spec=%s, pojo=%s]",
+ "[lazy not loaded]",
+ ""+getPojo());
+ }
+
+ private ObjectSpecification loadSpec() {
+ return specLoader.apply(pojo.getClass());
+ }
+
+ @Override
+ public void replacePojo(final UnaryOperator<Object> replacer) {
+ pojo = replacer.apply(pojo);
+ if(specification.isMemoized()) {
+ assertSpecIsInSyncWithPojo();
+ }
+ }
+
+}
\ No newline at end of file
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 a7a22701e3..9618294070 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
@@ -355,7 +355,7 @@ public interface ObjectAction extends ObjectMember {
hasImperativeFaIcon->
ManagedObjects.isNullOrUnspecifiedOrEmpty(domainObject)
? null
- :
hasImperativeFaIcon.getCssClassFaFactory(domainObject.asProvider())))
+ :
hasImperativeFaIcon.getCssClassFaFactory(domainObject.asSupplier())))
.filter(_NullSafe::isPresent);
}
@@ -410,7 +410,7 @@ public interface ObjectAction extends ObjectMember {
val mixinSpec = action.getDeclaringType();
val ownerSpec = mixeeAdapter.getSpecification();
return ownerSpec.lookupMixedInMember(mixinSpec)
-
.map(mixedInMember->mixedInMember.getFriendlyName(mixeeAdapter.asProvider()))
+
.map(mixedInMember->mixedInMember.getFriendlyName(mixeeAdapter.asSupplier()))
.orElseThrow(_Exceptions::unexpectedCodeReach);
}
return action.getFriendlyName(head::getOwner);
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java
index 2d6046fde9..69e49b224f 100644
---
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java
@@ -665,7 +665,7 @@ public class XmlSnapshot implements Snapshot {
// Skip field if we have seen the name already
for (int j = 0; j < i; j++) {
- if (Objects.equals(fieldName,
fields.get(i).getFriendlyName(adapter.asProvider()))) {
+ if (Objects.equals(fieldName,
fields.get(i).getFriendlyName(adapter.asSupplier()))) {
log.debug("objectToElement(NO): {} SKIPPED", log("field",
fieldName));
continue eachField;
}
diff --git
a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java
b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java
index 93796b25f4..8c7cfea9e6 100644
---
a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java
+++
b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java
@@ -147,8 +147,8 @@ extends AbstractObjectMemberReprRenderer<ObjectAction> {
final JsonRepresentation paramRep = JsonRepresentation.newMap();
paramRep.mapPutInt("num", paramMeta.getParameterIndex());
paramRep.mapPutString("id", paramMeta.getId());
- paramRep.mapPutString("name",
paramMeta.getFriendlyName(objectAdapter.asProvider()));
- paramRep.mapPut("description",
paramMeta.getDescription(objectAdapter.asProvider()));
+ paramRep.mapPutString("name",
paramMeta.getFriendlyName(objectAdapter.asSupplier()));
+ paramRep.mapPut("description",
paramMeta.getDescription(objectAdapter.asSupplier()));
final Object paramChoices = choicesFor(paramMod, paramNeg);
if (paramChoices != null) {
paramRep.mapPut("choices", paramChoices);
diff --git
a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java
b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java
index ce3ebdc732..08b24303ac 100644
---
a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java
+++
b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java
@@ -24,7 +24,7 @@ import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.base._Lazy;
import org.apache.isis.core.metamodel.interactions.managed.ActionInteraction;
import org.apache.isis.core.metamodel.object.ManagedObject;
-import org.apache.isis.core.metamodel.object.PackedManagedObject;
+import org.apache.isis.core.metamodel.object.ManagedObjects;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.metamodel.util.Facets;
@@ -77,7 +77,7 @@ public class ObjectAndActionInvocation {
// which is introspected eagerly on application start and should be
the binding contract
val actualReturnTypeSpec = returnedAdapter.getSpecification();
- if (returnedAdapter instanceof PackedManagedObject
+ if (ManagedObjects.isPacked(returnedAdapter)
|| isVector(actualReturnTypeSpec)) {
// though not strictly required, try to be consistent: empty list
vs populated list
diff --git
a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java
b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java
index 193851266a..eafe14eb41 100644
---
a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java
+++
b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java
@@ -119,9 +119,9 @@ public class ObjectAdapterUpdateHelper {
// otherwise, is an error.
final String invalidReason =
propertiesMap.getString("x-ro-invalidReason");
if(invalidReason != null) {
- propertiesMap.mapPutString("x-ro-invalidReason", invalidReason
+ "; " + property.getFriendlyName(objectAdapter.asProvider()));
+ propertiesMap.mapPutString("x-ro-invalidReason", invalidReason
+ "; " + property.getFriendlyName(objectAdapter.asSupplier()));
} else {
- propertiesMap.mapPutString("x-ro-invalidReason", "Mandatory
field(s) missing: " + property.getFriendlyName(objectAdapter.asProvider()));
+ propertiesMap.mapPutString("x-ro-invalidReason", "Mandatory
field(s) missing: " + property.getFriendlyName(objectAdapter.asSupplier()));
}
allOk = false;
return allOk;
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/icontitle/EntityIconAndTitlePanel.java
b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/icontitle/EntityIconAndTitlePanel.java
index d1fc7d02ad..8a85327e66 100644
---
a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/icontitle/EntityIconAndTitlePanel.java
+++
b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/icontitle/EntityIconAndTitlePanel.java
@@ -29,7 +29,6 @@ import org.apache.isis.commons.internal.base._Strings;
import
org.apache.isis.core.metamodel.facets.members.cssclassfa.CssClassFaFactory;
import org.apache.isis.core.metamodel.object.ManagedObject;
import org.apache.isis.core.metamodel.object.ManagedObjects;
-import org.apache.isis.core.metamodel.object.PackedManagedObject;
import org.apache.isis.core.metamodel.object.ManagedObjects.EntityUtil;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.viewer.wicket.model.models.EntityModel;
@@ -175,7 +174,7 @@ extends PanelAbstract<ManagedObject, ObjectAdapterModel> {
private String determineTitle() {
val managedObject = getModel().getObject();
- return managedObject instanceof PackedManagedObject
+ return ManagedObjects.isPacked(managedObject)
? "(multiple objects)"
: managedObject != null
?
managedObject.titleString(conf->conf.skipTitlePartEvaluator(this::isContextAdapter))
@@ -217,7 +216,7 @@ extends PanelAbstract<ManagedObject, ObjectAdapterModel> {
private static boolean isNonEmptyAbstractScalar(final ManagedObject obj) {
if(obj==null
|| obj.getPojo()==null
- || obj instanceof PackedManagedObject) {
+ || ManagedObjects.isPacked(obj)) {
return false;
}
return obj.getSpecification().isAbstract();