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 8a4b5b89ef1273bf93a5f2b262d16dd91fc16347 Author: Andi Huber <[email protected]> AuthorDate: Thu Sep 1 05:31:13 2022 +0200 ISIS-3167: implements the remaining VIEWMODEL and ENTITY (not active yet) --- .../core/metamodel/object/_ManagedObjectEmpty.java | 3 - ...dObjectMixin.java => _ManagedObjectEntity.java} | 59 ++++--- .../core/metamodel/object/_ManagedObjectMixin.java | 1 - .../core/metamodel/object/_ManagedObjectOther.java | 10 +- .../metamodel/object/_ManagedObjectService.java | 1 - .../core/metamodel/object/_ManagedObjectValue.java | 1 - .../metamodel/object/_ManagedObjectViewmodel.java | 189 +++++++++++++++++++++ 7 files changed, 233 insertions(+), 31 deletions(-) diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEmpty.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEmpty.java index 285211fabf..bf03745c66 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEmpty.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEmpty.java @@ -23,13 +23,10 @@ import java.util.function.Supplier; import org.apache.isis.applib.services.bookmark.Bookmark; import org.apache.isis.core.metamodel.spec.ObjectSpecification; -import lombok.Getter; - /** * (package private) specialization corresponding to {@link Specialization#EMPTY} * @see ManagedObject.Specialization#EMPTY */ -@Getter final class _ManagedObjectEmpty extends _ManagedObjectSpecified implements Bookmarkable.NoBookmark { diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectMixin.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntity.java similarity index 56% copy from core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectMixin.java copy to core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntity.java index 15fb7fafbd..91b8c9192c 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectMixin.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntity.java @@ -18,46 +18,65 @@ */ package org.apache.isis.core.metamodel.object; +import java.util.Optional; import java.util.function.Supplier; +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.exceptions._Exceptions; import org.apache.isis.core.metamodel.spec.ObjectSpecification; -import lombok.Getter; import lombok.NonNull; -import lombok.experimental.Accessors; /** - * (package private) specialization corresponding to {@link Specialization#MIXIN} - * @see ManagedObject.Specialization#MIXIN + * (package private) specialization corresponding to {@link Specialization#ENTITY} + * @see ManagedObject.Specialization#ENTITY */ -@Getter -final class _ManagedObjectMixin -extends _ManagedObjectSpecified -implements Bookmarkable.NoBookmark { +final class _ManagedObjectEntity +extends _ManagedObjectSpecified { - @Getter(onMethod_ = {@Override}) @Accessors(makeFinal = true) - private final @NonNull Object pojo; + private /*final*/ @Nullable Object pojo; + private final @NonNull Bookmark bookmark; - _ManagedObjectMixin( + _ManagedObjectEntity( final ObjectSpecification spec, - final Object pojo) { - super(ManagedObject.Specialization.MIXIN, spec); - _Assert.assertTrue(spec.isMixin()); + final Object pojo, + final @NonNull Bookmark bookmark) { + super(ManagedObject.Specialization.ENTITY, spec); this.pojo = assertCompliance(pojo); + this.bookmark = bookmark; + } + + @Override + public Optional<Bookmark> getBookmark() { + return Optional.of(bookmark); + } + + @Override + public Optional<Bookmark> getBookmarkRefreshed() { + return getBookmark(); // no-op for entities + } + + @Override + public boolean isBookmarkMemoized() { + return true; } @Override public void refreshViewmodel(final Supplier<Bookmark> bookmarkSupplier) { - // no-op for mixins + // no-op for entities } @Override - public final String getTitle() { - // mixins have no title - throw _Exceptions.unexpectedCodeReach(); + public Object getPojo() { + // TODO refetch if required + return pojo; } + // -- HELPER + +// private EntityFacet entityFacet() { +// return getSpecification().entityFacet().orElseThrow(); +// } + } \ No newline at end of file diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectMixin.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectMixin.java index 15fb7fafbd..e635a0145c 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectMixin.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectMixin.java @@ -33,7 +33,6 @@ import lombok.experimental.Accessors; * (package private) specialization corresponding to {@link Specialization#MIXIN} * @see ManagedObject.Specialization#MIXIN */ -@Getter final class _ManagedObjectMixin extends _ManagedObjectSpecified implements Bookmarkable.NoBookmark { diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectOther.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectOther.java index 62a7a88a98..4618fad95a 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectOther.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectOther.java @@ -31,7 +31,6 @@ import lombok.experimental.Accessors; * (package private) specialization corresponding to {@link Specialization#OTHER} * @see ManagedObject.Specialization#OTHER */ -@Getter final class _ManagedObjectOther extends _ManagedObjectSpecified implements Bookmarkable.NoBookmark { @@ -53,9 +52,10 @@ implements Bookmarkable.NoBookmark { // no-op for other } - @Override - public String getTitle() { - return "other object"; - } + //TODO to use or not to use? +// @Override +// public String getTitle() { +// return "other object"; +// } } \ No newline at end of file diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectService.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectService.java index aa9b839b9d..fd1f168a9f 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectService.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectService.java @@ -34,7 +34,6 @@ import lombok.experimental.Accessors; * (package private) specialization corresponding to {@link Specialization#SERVICE} * @see ManagedObject.Specialization#SERVICE */ -@Getter final class _ManagedObjectService extends _ManagedObjectSpecified { diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectValue.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectValue.java index 2a6e1be759..f6795095af 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectValue.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectValue.java @@ -37,7 +37,6 @@ import lombok.experimental.Accessors; * (package private) specialization corresponding to {@link Specialization#VALUE} * @see ManagedObject.Specialization#VALUE */ -@Getter final class _ManagedObjectValue extends _ManagedObjectSpecified { diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectViewmodel.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectViewmodel.java new file mode 100644 index 0000000000..3ab20f9fd1 --- /dev/null +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectViewmodel.java @@ -0,0 +1,189 @@ +/* + * 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.assertions._Assert; +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.Getter; +import lombok.NonNull; +import lombok.val; + +/** + * (package private) specialization corresponding to {@link Specialization#VIEWMODEL} + * @see ManagedObject.Specialization#VIEWMODEL + */ +final class _ManagedObjectViewmodel +extends _ManagedObjectSpecified { + + @Getter(onMethod_ = {@Override}) + @Nullable private /*final*/ Object pojo; + + protected final _Lazy<Optional<Bookmark>> bookmarkLazy = + _Lazy.threadSafe(()->bookmark(this)); + + _ManagedObjectViewmodel( + final ObjectSpecification spec, + final Object pojo, + final Optional<Bookmark> bookmarkIfKnown) { + super(ManagedObject.Specialization.VIEWMODEL, spec); + _Assert.assertTrue(spec.isViewModel()); + this.pojo = assertCompliance(pojo); + if(bookmarkIfKnown.isPresent()) { + this.bookmarkLazy.set(bookmarkIfKnown); + } + } + + @Override + public final Optional<Bookmark> getBookmark() { + return bookmarkLazy.get(); + } + + @Override + public final boolean isBookmarkMemoized() { + return bookmarkLazy.isMemoized(); + } + + @Override + public final Optional<Bookmark> getBookmarkRefreshed() { + 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); + } + } + } + } + } + + // -- HELPER + + 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); + } + } + + private void replacePojo(final UnaryOperator<Object> replacer) { + pojo = assertCompliance(replacer.apply(pojo)); + } + +} \ No newline at end of file
