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 2019/01/30 21:57:18 UTC
[isis] branch 2033-IoC updated: ISIS-2033: introduces a new Oid
'UniversalOid'
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch 2033-IoC
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/2033-IoC by this push:
new 188bcf6 ISIS-2033: introduces a new Oid 'UniversalOid'
188bcf6 is described below
commit 188bcf65e2b8c6772d2ecbf73025cac7aef35966
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Jan 30 22:57:10 2019 +0100
ISIS-2033: introduces a new Oid 'UniversalOid'
to access/reference Beans and Entities managed ba external IoC
containers or PersistenceContexts
Task-Url: https://issues.apache.org/jira/browse/ISIS-2033
---
.../applib/services/inject/ServiceInjector.java | 2 +-
.../apache/isis/commons/internal/base/_Casts.java | 60 +++++++++
.../isis/commons/internal/base/_Strings.java | 25 ++++
.../commons/internal/base/_Strings_FastSplit.java | 48 +++++++
.../org/apache/isis/commons/internal/cdi/_CDI.java | 43 +++++-
.../internal/cdi/_CDI_AmbiguousInstance.java | 58 ++++++++
.../commons/internal/cdi/_CDI_EmptyInstance.java | 65 +++++++++
.../internal/cdi/_CDI_SingletonInstance.java | 63 +++++++++
.../org/apache/isis/commons/internal/uri/_URI.java | 146 +++++++++++++++++++++
.../isis/core/metamodel/adapter/ObjectAdapter.java | 2 +-
.../metamodel/adapter/ObjectAdapterProvider.java | 15 ---
.../isis/core/metamodel/adapter/oid/Oid.java | 8 ++
.../isis/core/metamodel/adapter/oid/Oid_Root.java | 11 ++
.../core/metamodel/adapter/oid/Oid_Universal.java | 141 ++++++++++++++++++++
.../core/metamodel/adapter/oid/UniversalOid.java | 9 ++
.../isis/core/metamodel/spec/ManagedObject.java | 15 ++-
.../metamodel/specloader/SpecificationLoader.java | 3 +-
.../isis/core/plugins/ioc/weld/WeldFactory.java | 1 -
.../core/runtime/contextmanger/ContextHandler.java | 28 ++++
.../core/runtime/contextmanger/ContextManager.java | 12 ++
.../contextmanger/ManagedObjectResolver.java | 33 +++++
.../contextmanger/UniversalContextManager.java | 73 +++++++++++
.../runtime/persistence/adapter/PojoAdapter.java | 22 +++-
.../adaptermanager/ObjectAdapterContext.java | 10 +-
...ctAdapterContext_ObjectAdapterByIdProvider.java | 47 ++++++-
...ObjectAdapterContext_ObjectAdapterProvider.java | 10 +-
.../ObjectAdapterContext_OidProviders.java | 109 ++++++++-------
.../adaptermanager/factories/OidFactory.java | 5 +-
.../factories/OidFactory_Builder.java | 15 ++-
.../system/session/IsisSessionProducerBean.java | 5 +-
.../wicket/viewer/IsisWicketApplication.java | 2 +-
.../wicket/ConverterForObjectAdapterMemento.java | 2 +-
.../model/mementos/ObjectAdapterMemento.java | 22 +++-
.../wicket/model/models/EntityCollectionModel.java | 2 +-
.../viewer/wicket/model/models/EntityModel.java | 6 +-
.../model/models/EntityModelForReference.java | 2 +-
.../viewer/wicket/model/models/ValueModel.java | 2 +-
.../entityactions/EntityActionLinkFactory.java | 2 +-
.../wicket/ui/panels/FormExecutorDefault.java | 28 +++-
.../application/manifest/menubars.layout.xml | 13 ++
.../modules/spring/SpringDataJPADemoHandler.java | 100 ++++++++++++++
41 files changed, 1152 insertions(+), 113 deletions(-)
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/inject/ServiceInjector.java b/core/applib/src/main/java/org/apache/isis/applib/services/inject/ServiceInjector.java
index 352c5d1..c700f98 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/inject/ServiceInjector.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/inject/ServiceInjector.java
@@ -45,7 +45,7 @@ public interface ServiceInjector {
@Deprecated // use ServiceRegistry instead
<T> T lookupServiceElseFail(final Class<T> serviceClass);
-//FIXME [2033]
+//FIXME [2033] remove comments ...
// /**
// * This is mutable internally, but only ever exposed (in {@link #streamRegisteredServices()}).
// */
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Casts.java b/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Casts.java
index a8365a9..ac56798 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Casts.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Casts.java
@@ -21,6 +21,7 @@ package org.apache.isis.commons.internal.base;
import static org.apache.isis.commons.internal.base._With.requires;
+import java.util.function.BiFunction;
import java.util.function.Supplier;
import javax.annotation.Nullable;
@@ -63,4 +64,63 @@ public final class _Casts {
}
+ /**
+ * Dependent on whether left or right can be cast to {@code cls}, the appropriate functional
+ * interface is chosen to produce the result.
+ * @param left
+ * @param right
+ * @param cls
+ * @param onBothCast
+ * @param onLeftCast
+ * @param onRightCast
+ * @param onNonCast
+ * @return
+ */
+ public static <T, R, U, V> R castThenApply(
+ @Nullable U left,
+ @Nullable V right,
+ Class<T> cls,
+ BiFunction<T, T, R> onBothCast,
+ BiFunction<T, V, R> onLeftCast,
+ BiFunction<U, T, R> onRightCast,
+ BiFunction<U, V, R> onNonCast) {
+
+ requires(cls, "cls");
+
+ T left_casted=null, right_casted=null;
+ boolean left_not_casted=false, right_not_casted=false;
+
+ if(left==null) {
+ left_casted = null;
+ } else if(cls.isAssignableFrom(left.getClass())) {
+ left_casted = cls.cast(left);
+ } else {
+ left_not_casted = true;
+ }
+
+ if(right==null) {
+ right_casted = null;
+ } else if(cls.isAssignableFrom(right.getClass())) {
+ right_casted = cls.cast(right);
+ } else {
+ right_not_casted = true;
+ }
+
+ if(left_not_casted && right_not_casted) {
+ return onNonCast.apply(left, right);
+ }
+
+ if(!left_not_casted && !right_not_casted) {
+ return onBothCast.apply(left_casted, right_casted);
+ }
+
+ if(left_not_casted) {
+ return onRightCast.apply(left, right_casted);
+ }
+
+ return onLeftCast.apply(left_casted, right);
+
+ }
+
+
}
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Strings.java b/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Strings.java
index 151cfc7..7e6226f 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Strings.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Strings.java
@@ -33,6 +33,8 @@ import java.util.Optional;
import java.util.Scanner;
import java.util.Spliterator;
import java.util.Spliterators;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
import java.util.function.UnaryOperator;
import java.util.regex.Pattern;
import java.util.stream.Stream;
@@ -365,6 +367,29 @@ public final class _Strings {
}
return delimiterPattern.splitAsStream(input);
}
+
+
+ public static void splitThenAccept(
+ @Nullable final String input,
+ final String separator,
+ final BiConsumer<String, String> onNonEmptySplit,
+ final Consumer<String> onNonEmptyLhs,
+ final Consumer<String> onNonEmptyRhs) {
+
+ _Strings_FastSplit.splitThenAccept(input, separator, onNonEmptySplit, onNonEmptyLhs, onNonEmptyRhs);
+ }
+
+ public static void splitThenAcceptEmptyAsNull(
+ @Nullable final String input,
+ final String separator,
+ final BiConsumer<String, String> onSplit) {
+
+ _Strings_FastSplit.splitThenAccept(input, separator, onSplit,
+ lhs->onSplit.accept(lhs, null),
+ rhs->onSplit.accept(null, rhs));
+ }
+
+
// -- REPLACEMENT OPERATORS
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Strings_FastSplit.java b/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Strings_FastSplit.java
new file mode 100644
index 0000000..1eac561
--- /dev/null
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Strings_FastSplit.java
@@ -0,0 +1,48 @@
+package org.apache.isis.commons.internal.base;
+
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+import javax.annotation.Nullable;
+
+class _Strings_FastSplit {
+
+ public static void splitThenAccept(
+ @Nullable final String input,
+ final String separator,
+ BiConsumer<String, String> onNonEmptySplit,
+ Consumer<String> onNonEmptyLhs,
+ Consumer<String> onNonEmptyRhs) {
+
+ if(_Strings.isEmpty(input)) {
+ // skip
+ return;
+ }
+
+ // we have a non-empty string
+
+ final int p = input.indexOf(separator);
+ if(p<1){
+ if(p==-1) {
+ // separator not found
+ onNonEmptyLhs.accept(input);
+ return;
+ }
+ if(p==0) {
+ // empty lhs in string
+ if(input.length()>separator.length()) {
+ onNonEmptyRhs.accept(input);
+ }
+ return;
+ }
+ }
+ final int q = p + separator.length();
+ if(q==input.length()) {
+ // empty rhs
+ onNonEmptyLhs.accept(input.substring(0, p));
+ return;
+ }
+ onNonEmptySplit.accept(input.substring(0, p), input.substring(q));
+ }
+
+}
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/cdi/_CDI.java b/core/commons/src/main/java/org/apache/isis/commons/internal/cdi/_CDI.java
index 79b5277..0400caf 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/cdi/_CDI.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/cdi/_CDI.java
@@ -18,6 +18,10 @@
*/
package org.apache.isis.commons.internal.cdi;
+import static org.apache.isis.commons.internal.base._NullSafe.isEmpty;
+import static org.apache.isis.commons.internal.base._NullSafe.stream;
+import static org.apache.isis.commons.internal.base._With.requires;
+
import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.List;
@@ -28,6 +32,7 @@ import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import javax.annotation.Nullable;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.spi.Bean;
@@ -37,14 +42,13 @@ import javax.enterprise.inject.spi.CDIProvider;
import javax.enterprise.util.AnnotationLiteral;
import javax.inject.Qualifier;
+import org.apache.isis.commons.internal.base._NullSafe;
import org.apache.isis.commons.internal.context._Context;
import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.commons.internal.functions._Functions.CheckedRunnable;
import org.apache.isis.core.plugins.ioc.IocPlugin;
-import static org.apache.isis.commons.internal.base._NullSafe.isEmpty;
-import static org.apache.isis.commons.internal.base._NullSafe.stream;
-import static org.apache.isis.commons.internal.base._With.requires;
+import lombok.val;
/**
* <h1>- internal use only -</h1>
@@ -221,6 +225,38 @@ public final class _CDI {
Set<Bean<?>> beans = beanManager.getBeans(Object.class, _CDI.QUALIFIER_ANY);
return beans.stream();
}
+
+ // -- FACTORIES
+
+ public static class InstanceFactory {
+
+ public static <T> Instance<T> empty() {
+ return new _CDI_EmptyInstance<>();
+ }
+
+ public static <T> Instance<T> singleton(@Nullable T pojo) {
+ if(pojo==null) {
+ return empty();
+ }
+ return _CDI_SingletonInstance.of(pojo);
+ }
+
+ public static <T> Instance<T> ambiguous(@Nullable Collection<T> collection) {
+ val size = _NullSafe.size(collection);
+ if(size==0) {
+ return empty();
+ }
+ if(size==1) {
+ if(collection instanceof List) {
+ // just to reduce heap pollution when collection is a list
+ return singleton(((List<T>)collection).get(0));
+ }
+ return singleton(collection.iterator().next());
+ }
+ return _CDI_AmbiguousInstance.of(collection);
+ }
+
+ }
// -- HELPER
@@ -246,7 +282,6 @@ public final class _CDI {
return null;
}
}
-
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/cdi/_CDI_AmbiguousInstance.java b/core/commons/src/main/java/org/apache/isis/commons/internal/cdi/_CDI_AmbiguousInstance.java
new file mode 100644
index 0000000..1c52594
--- /dev/null
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/cdi/_CDI_AmbiguousInstance.java
@@ -0,0 +1,58 @@
+package org.apache.isis.commons.internal.cdi;
+
+import java.lang.annotation.Annotation;
+import java.util.Iterator;
+
+import javax.enterprise.inject.Instance;
+import javax.enterprise.util.TypeLiteral;
+
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor(staticName="of")
+final class _CDI_AmbiguousInstance<T> implements Instance<T> {
+
+ private final Iterable<T> iterable;
+
+ @Override
+ public Iterator<T> iterator() {
+ return iterable.iterator();
+ }
+
+ @Override
+ public T get() {
+ throw _Exceptions.notImplemented();
+ }
+
+ @Override
+ public Instance<T> select(Annotation... qualifiers) {
+ throw _Exceptions.notImplemented();
+ }
+
+ @Override
+ public <U extends T> Instance<U> select(Class<U> subtype, Annotation... qualifiers) {
+ throw _Exceptions.notImplemented();
+ }
+
+ @Override
+ public <U extends T> Instance<U> select(TypeLiteral<U> subtype, Annotation... qualifiers) {
+ throw _Exceptions.notImplemented();
+ }
+
+ @Override
+ public boolean isUnsatisfied() {
+ return false;
+ }
+
+ @Override
+ public boolean isAmbiguous() {
+ return true;
+ }
+
+ @Override
+ public void destroy(T instance) {
+ // ignore
+ }
+
+}
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/cdi/_CDI_EmptyInstance.java b/core/commons/src/main/java/org/apache/isis/commons/internal/cdi/_CDI_EmptyInstance.java
new file mode 100644
index 0000000..28d5e8c
--- /dev/null
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/cdi/_CDI_EmptyInstance.java
@@ -0,0 +1,65 @@
+package org.apache.isis.commons.internal.cdi;
+
+import java.lang.annotation.Annotation;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.enterprise.inject.Instance;
+import javax.enterprise.util.TypeLiteral;
+
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+
+final class _CDI_EmptyInstance<T> implements Instance<T> {
+
+ @Override
+ public Iterator<T> iterator() {
+ return new Iterator<T>() {
+
+ @Override
+ public boolean hasNext() {
+ return false;
+ }
+
+ @Override
+ public T next() {
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
+ @Override
+ public T get() {
+ throw new NoSuchElementException();
+ }
+
+ @Override
+ public Instance<T> select(Annotation... qualifiers) {
+ throw _Exceptions.notImplemented();
+ }
+
+ @Override
+ public <U extends T> Instance<U> select(Class<U> subtype, Annotation... qualifiers) {
+ throw _Exceptions.notImplemented();
+ }
+
+ @Override
+ public <U extends T> Instance<U> select(TypeLiteral<U> subtype, Annotation... qualifiers) {
+ throw _Exceptions.notImplemented();
+ }
+
+ @Override
+ public boolean isUnsatisfied() {
+ return true;
+ }
+
+ @Override
+ public boolean isAmbiguous() {
+ return false;
+ }
+
+ @Override
+ public void destroy(T instance) {
+ // ignore
+ }
+
+}
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/cdi/_CDI_SingletonInstance.java b/core/commons/src/main/java/org/apache/isis/commons/internal/cdi/_CDI_SingletonInstance.java
new file mode 100644
index 0000000..33cec4c
--- /dev/null
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/cdi/_CDI_SingletonInstance.java
@@ -0,0 +1,63 @@
+package org.apache.isis.commons.internal.cdi;
+
+import java.lang.annotation.Annotation;
+import java.util.Collections;
+import java.util.Iterator;
+
+import javax.enterprise.inject.Instance;
+import javax.enterprise.util.TypeLiteral;
+
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor(staticName="of")
+final class _CDI_SingletonInstance<T> implements Instance<T> {
+
+ private final T singleton;
+ private Iterable<T> iterable;
+
+ @Override
+ public Iterator<T> iterator() {
+ if(iterable==null) {
+ iterable = Collections.singletonList(singleton);
+ }
+ return iterable.iterator();
+ }
+
+ @Override
+ public T get() {
+ return singleton;
+ }
+
+ @Override
+ public Instance<T> select(Annotation... qualifiers) {
+ throw _Exceptions.notImplemented();
+ }
+
+ @Override
+ public <U extends T> Instance<U> select(Class<U> subtype, Annotation... qualifiers) {
+ throw _Exceptions.notImplemented();
+ }
+
+ @Override
+ public <U extends T> Instance<U> select(TypeLiteral<U> subtype, Annotation... qualifiers) {
+ throw _Exceptions.notImplemented();
+ }
+
+ @Override
+ public boolean isUnsatisfied() {
+ return false;
+ }
+
+ @Override
+ public boolean isAmbiguous() {
+ return false;
+ }
+
+ @Override
+ public void destroy(T instance) {
+ // ignore
+ }
+
+}
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/uri/_URI.java b/core/commons/src/main/java/org/apache/isis/commons/internal/uri/_URI.java
new file mode 100644
index 0000000..306f33d
--- /dev/null
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/uri/_URI.java
@@ -0,0 +1,146 @@
+package org.apache.isis.commons.internal.uri;
+
+import static org.apache.isis.commons.internal.base._Strings.splitThenAcceptEmptyAsNull;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.commons.internal.uri._URI.UoidDto.UoidDtoBuilder;
+import org.apache.isis.commons.internal.uri._URI.UriDto.UriDtoBuilder;
+
+import lombok.Builder;
+import lombok.ToString;
+import lombok.val;
+
+/**
+ * @since 2.0.0-M3
+ */
+public final class _URI {
+
+ // -- URI
+
+ public static UriDtoBuilder uriBuilder() {
+ return UriDto.builder();
+ }
+
+ public static UriDtoBuilder uriBuilder(URI template) {
+ val builder = UriDto.builder()
+ .scheme(template.getScheme())
+ .authority(template.getAuthority())
+ .path(template.getPath())
+ .query(template.getQuery())
+ .fragment(template.getFragment());
+ return builder;
+ }
+
+ @Builder @ToString
+ public static class UriDto {
+ private final String scheme;
+ private final String authority;
+ private final String path;
+ private final String query;
+ private final String fragment;
+
+ public URI toURI() {
+ try {
+ return new URI(scheme, authority, path, query, fragment);
+ } catch (URISyntaxException e) {
+ throw _Exceptions.unrecoverable(e);
+ }
+ }
+
+ }
+
+ // -- UOID
+
+ private final static String UOID_SCHEME = "uoid";
+
+ public static boolean isUoid(String string) {
+ return string!=null && string.startsWith(UOID_SCHEME + "://");
+ }
+
+ public static UoidDtoBuilder uoidBuilder() {
+ return UoidDto.builder();
+ }
+
+ public static UoidDtoBuilder uoidBuilder(URI template) {
+ val builder = UoidDto.builder()
+ .scheme(template.getScheme())
+ .path(template.getPath())
+ .query(template.getQuery())
+ .fragment(template.getFragment());
+
+ splitThenAcceptEmptyAsNull(template.getAuthority(), "@",
+ (ctxType, rhs)->{
+ builder.contextType(ctxType!=null ? ContextType.valueOf(ctxType) : null);
+
+ splitThenAcceptEmptyAsNull(rhs, ":",
+ (cont, ctxId)->{
+ builder.containerType(cont!=null ? ContainerType.valueOf(cont) : null);
+ builder.contextId(ctxId);
+ });
+ });
+
+
+
+ return builder;
+
+ }
+
+ public static enum ContainerType {
+ cdi,
+ spring,
+ ;
+ }
+
+ public static enum ContextType {
+ beans, // InversionOfControlContainer
+ entities, // PersistenceContext
+ ;
+ }
+
+ @Builder @ToString
+ public static class UoidDto {
+ @Builder.Default private final String scheme = UOID_SCHEME;
+ @Builder.Default private final ContainerType containerType = ContainerType.cdi;
+ @Builder.Default private final ContextType contextType = ContextType.beans;
+ private final String contextId;
+ private final String path;
+ private final String query;
+ private final String fragment;
+
+ public URI toURI() {
+ try {
+ return new URI(scheme, authority(), path, query, fragment);
+ } catch (URISyntaxException e) {
+ throw _Exceptions.unrecoverable(e);
+ }
+ }
+
+ // -- HELPER
+
+ private String authority() {
+ val sb = new StringBuilder();
+ if(contextType!=null) {
+ sb.append(contextType.name()).append("@");
+ }
+ if(containerType!=null) {
+ sb.append(containerType.name());
+ }
+ if(!_Strings.isEmpty(contextId)) {
+ sb.append(":").append(contextId);
+ }
+ return sb.toString();
+ }
+
+
+ }
+
+ //-- HELPER
+
+ private _URI() {}
+
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java
index 74cc47a..160730a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapter.java
@@ -77,7 +77,7 @@ public interface ObjectAdapter extends ManagedObject {
Oid getOid();
/**
- * Returns either itself (if this is a root) or the parented collections, the
+ * Returns either itself (if this is a root) or for parented collections, the
* adapter corresponding to their {@link ParentedOid#getParentOid() root oid}.
*/
ObjectAdapter getAggregateRoot();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
index 4d80ecb..b66baf2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
@@ -24,7 +24,6 @@ import java.util.stream.Stream;
import javax.annotation.Nullable;
-import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.core.metamodel.adapter.oid.Oid;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
import org.apache.isis.core.metamodel.spec.ManagedObject;
@@ -44,7 +43,6 @@ public interface ObjectAdapterProvider {
* @param pojo
* @return oid for the given domain object
*/
- @Programmatic
default @Nullable Oid oidFor(@Nullable Object domainObject) {
return mapIfPresentElse(adapterFor(domainObject), ObjectAdapter::getOid, null);
}
@@ -109,15 +107,12 @@ public interface ObjectAdapterProvider {
public static interface Delegating extends ObjectAdapterProvider {
- @Programmatic
ObjectAdapterProvider getObjectAdapterProvider();
- @Programmatic
default ObjectAdapter adapterFor(Object domainObject) {
return getObjectAdapterProvider().adapterFor(domainObject);
}
- @Programmatic
default ObjectAdapter adapterFor(
final Object pojo,
final RootOid parentOid,
@@ -125,45 +120,35 @@ public interface ObjectAdapterProvider {
return getObjectAdapterProvider().adapterFor(pojo, parentOid, collection);
}
- @Programmatic
default ManagedObject disposableAdapterForViewModel(final Object viewModelPojo) {
return getObjectAdapterProvider().disposableAdapterForViewModel(viewModelPojo);
}
- @Programmatic
default ObjectSpecification specificationForViewModel(Object viewModelPojo) {
return getObjectAdapterProvider().specificationForViewModel(viewModelPojo);
}
- @Programmatic
default ObjectAdapter adapterForViewModel(final Object viewModelPojo, final String mementoString) {
return getObjectAdapterProvider().adapterForViewModel(viewModelPojo, mementoString);
}
- @Programmatic
default ObjectAdapter newTransientInstance(ObjectSpecification objectSpec) {
return getObjectAdapterProvider().newTransientInstance(objectSpec);
}
- @Programmatic
default ObjectAdapter recreateViewModelInstance(ObjectSpecification objectSpec, final String memento) {
return getObjectAdapterProvider().recreateViewModelInstance(objectSpec, memento);
}
- @Programmatic
default Stream<ObjectAdapter> streamServices() {
return getObjectAdapterProvider().streamServices();
}
- @Programmatic
default ObjectAdapter lookupService(String serviceId) {
return getObjectAdapterProvider().lookupService(serviceId);
}
}
-
-
-
}
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 9ddeb17..c12947e 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
@@ -19,6 +19,8 @@
package org.apache.isis.core.metamodel.adapter.oid;
+import java.net.URI;
+
import org.apache.isis.applib.annotation.Value;
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.core.commons.encoding.Encodable;
@@ -110,6 +112,12 @@ public interface Oid extends Encodable {
return Oid_Value.INSTANCE;
}
+ public static UniversalOid universal(URI uri) {
+ return Oid_Universal.of(uri);
+ }
+
+ // -- LEGACY
+
public static RootOid ofBookmark(final Bookmark bookmark) {
return Oid_Root.of(ObjectSpecId.of(bookmark.getObjectType()),
bookmark.getIdentifier(), Oid_State.from(bookmark), Version.empty());
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 98f1d67..57cfddc 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
@@ -25,6 +25,7 @@ import java.io.IOException;
import java.util.Objects;
import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.commons.encoding.DataInputExtended;
import org.apache.isis.core.commons.encoding.DataOutputExtended;
import org.apache.isis.core.commons.url.UrlDecoderUtil;
@@ -32,6 +33,8 @@ import org.apache.isis.core.metamodel.adapter.version.Version;
import org.apache.isis.core.metamodel.spec.ObjectSpecId;
import org.apache.isis.schema.common.v1.OidDto;
+import lombok.val;
+
final class Oid_Root implements RootOid {
// -- fields
@@ -69,6 +72,14 @@ final class Oid_Root implements RootOid {
this.state = state;
this.version = version;
this.hashCode = calculateHash();
+
+
+ val debug = this.toString();
+ if(debug.contains("/spring/")) {
+ _Exceptions.throwUnexpectedCodeReach();
+ }
+
+
}
// -- Encodeable
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Universal.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Universal.java
new file mode 100644
index 0000000..4f33110
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Universal.java
@@ -0,0 +1,141 @@
+/*
+ * 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.adapter.oid;
+
+import java.io.IOException;
+import java.net.URI;
+
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.commons.internal.debug._Probe;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.commons.internal.uri._URI;
+import org.apache.isis.core.commons.encoding.DataOutputExtended;
+import org.apache.isis.core.metamodel.adapter.version.Version;
+import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.schema.common.v1.OidDto;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import lombok.val;
+
+@RequiredArgsConstructor(staticName="of")
+final class Oid_Universal implements UniversalOid {
+
+ private final static long serialVersionUID = 1L;
+ private final static _Probe probe = _Probe.unlimited().label("Oid_Universal");
+
+ private final URI universalId;
+ @Getter @Setter private Version version;
+
+ @Override
+ public ObjectSpecId getObjectSpecId() {
+
+ val path = universalId().getPath();
+
+ val firstPathEntry = _Strings.splitThenStream(path, "/")
+ .filter(_Strings::isNotEmpty)
+ .findFirst()
+ .orElse(null);
+
+ return ObjectSpecId.of(firstPathEntry);
+ }
+
+ @Override
+ public String getIdentifier() {
+ return universalId().getQuery();
+ }
+
+ @Override
+ public Bookmark asBookmark() {
+
+ //TODO [2033] bad place to do this here, change API ?
+ //probe.println("NOT IMPLEMENTED: 'asBookmark()'");
+
+ final String objectType = getObjectSpecId().asString();
+ //asBookmarkObjectState().getCode() + rootOid.getObjectSpecId().asString();
+ final String identifier = universalId().getQuery();
+ //rootOid.getIdentifier();
+
+ return new Bookmark(objectType, identifier);
+
+ }
+
+ @Override
+ public OidDto asOidDto() {
+ _Exceptions.throwNotImplemented();
+
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String enString() {
+ if(version==null) {
+ return enStringNoVersion();
+ }
+ return _URI.uriBuilder(universalId)
+ .fragment(version.enString())
+ .build()
+ .toURI()
+ .toString();
+ }
+
+ @Override
+ public String enStringNoVersion() {
+ return universalId.toString();
+ }
+
+ @Override
+ public boolean isTransient() {
+ return false;
+ }
+
+ @Override
+ public boolean isViewModel() {
+ return false;
+ }
+
+ @Override
+ public boolean isPersistent() {
+ return true;
+ }
+
+ @Override
+ public Oid copy() {
+ return of(universalId());
+ }
+
+ @Override
+ public void encode(DataOutputExtended outputStream) throws IOException {
+ _Exceptions.throwNotImplemented();
+
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public URI universalId() {
+ return universalId;
+ }
+
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/UniversalOid.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/UniversalOid.java
new file mode 100644
index 0000000..5773b37
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/UniversalOid.java
@@ -0,0 +1,9 @@
+package org.apache.isis.core.metamodel.adapter.oid;
+
+import java.net.URI;
+
+public interface UniversalOid extends RootOid {
+
+ URI universalId();
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
index 1409ff9..46bc043 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
@@ -25,8 +25,13 @@ import org.apache.isis.commons.internal.base._Lazy;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Value;
+
/**
- * Represents an instance of some element of the meta-model managed by the framework.
+ * Represents an instance of some element of the meta-model managed by the framework,
+ * that is IoC-container provided beans or persistence-stack provided entities.
*
*/
public interface ManagedObject {
@@ -42,6 +47,14 @@ public interface ManagedObject {
*/
Object getPojo();
+ // -- SIMPLE
+
+ @Value @RequiredArgsConstructor(staticName="of")
+ public final static class SimpleManagedObject implements ManagedObject {
+ @Getter private final ObjectSpecification specification;
+ @Getter private final Object pojo;
+ }
+
// -- TITLE
public default String titleString() {
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 2e607ed..5cf33b2 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
@@ -66,7 +66,6 @@ import org.apache.isis.core.metamodel.specloader.validator.ValidationFailures;
import org.apache.isis.core.runtime.threadpool.ThreadPoolExecutionMode;
import org.apache.isis.core.runtime.threadpool.ThreadPoolSupport;
import org.apache.isis.progmodels.dflt.ProgrammingModelFacetsJava5;
-import org.apache.isis.schema.metamodel.v1.MetamodelDto;
import org.apache.isis.schema.utils.CommonDtoUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -216,7 +215,7 @@ public class SpecificationLoader {
LOG.info("init() - done");
- //FIXME [2033] remove
+ //FIXME [2033] remove debug code ...
{
streamServiceClasses()
.forEach(service->probe.println("using service %s", service));
diff --git a/core/plugins/ioc-weld/src/main/java/org/apache/isis/core/plugins/ioc/weld/WeldFactory.java b/core/plugins/ioc-weld/src/main/java/org/apache/isis/core/plugins/ioc/weld/WeldFactory.java
index 4627805..c322b75 100644
--- a/core/plugins/ioc-weld/src/main/java/org/apache/isis/core/plugins/ioc/weld/WeldFactory.java
+++ b/core/plugins/ioc-weld/src/main/java/org/apache/isis/core/plugins/ioc/weld/WeldFactory.java
@@ -62,7 +62,6 @@ public class WeldFactory {
"org.apache.isis.core.wrapper.WrapperFactoryDefault",
"org.apache.isis.viewer.wicket.viewer.IsisWicketModule",
"org.apache.isis.applib.services.jdosupport.IsisJdoSupportDN5",
- "org.apache.isis.core.runtime.services.ServiceInstantiator",
"org.apache.wicket.cdi.AutoConversation",
"org.apache.isis.viewer.restfulobjects.rendering.RendererContext"
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/contextmanger/ContextHandler.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/contextmanger/ContextHandler.java
new file mode 100644
index 0000000..477c988
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/contextmanger/ContextHandler.java
@@ -0,0 +1,28 @@
+package org.apache.isis.core.runtime.contextmanger;
+
+import java.net.URI;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+/**
+ * @since 2.0.0-M3
+ */
+public interface ContextHandler extends ManagedObjectResolver {
+
+ /**
+ * To support chain-of-responsibility pattern.
+ * @param objectSpec
+ * @return whether this manager sees itself responsible to manage objects represented by given objectSpec
+ */
+ boolean recognizes(ObjectSpecification objectSpec);
+
+ /**
+ * To support chain-of-responsibility pattern.
+ * @param uri
+ * @return whether this manager sees itself responsible to manage objects represented by given uri
+ */
+ boolean recognizes(URI uri);
+
+
+
+}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/contextmanger/ContextManager.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/contextmanger/ContextManager.java
new file mode 100644
index 0000000..69fe5ba
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/contextmanger/ContextManager.java
@@ -0,0 +1,12 @@
+package org.apache.isis.core.runtime.contextmanger;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+/**
+ * @since 2.0.0-M3
+ */
+public interface ContextManager extends ManagedObjectResolver {
+
+ ManagedObjectResolver resolverFor(ObjectSpecification spec);
+
+}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/contextmanger/ManagedObjectResolver.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/contextmanger/ManagedObjectResolver.java
new file mode 100644
index 0000000..08ce300
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/contextmanger/ManagedObjectResolver.java
@@ -0,0 +1,33 @@
+package org.apache.isis.core.runtime.contextmanger;
+
+import java.net.URI;
+
+import javax.enterprise.inject.Instance;
+
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+
+/**
+ * @since 2.0.0-M3
+ */
+public interface ManagedObjectResolver {
+
+ /**
+ * Returns object identifier, which holds sufficient information for the framework to
+ * retrieve a reference to given managedObject later.
+ *
+ * @param managedObject
+ * @return identifier
+ */
+ URI identifierOf(ManagedObject managedObject);
+
+
+ /**
+ * Retrieve a reference to the ManagedObject as identified by the identifier.
+ * @param spec
+ * @param identifier
+ * @return
+ */
+ Instance<ManagedObject> resolve(ObjectSpecId spec, URI identifier);
+
+}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/contextmanger/UniversalContextManager.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/contextmanger/UniversalContextManager.java
new file mode 100644
index 0000000..7ef59ad
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/contextmanger/UniversalContextManager.java
@@ -0,0 +1,73 @@
+package org.apache.isis.core.runtime.contextmanger;
+
+import static org.apache.isis.commons.internal.base._With.requires;
+
+import java.net.URI;
+
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+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;
+
+@Singleton
+public class UniversalContextManager implements ContextManager {
+
+ @Inject Instance<ContextHandler> contextHandlers;
+
+ @Override
+ public URI identifierOf(ManagedObject managedObject) {
+
+ requires(managedObject, "managedObject");
+
+ val resolver = resolverFor(managedObject.getSpecification());
+ if(resolver==null) {
+ val msg = String.format(
+ "Could not find a ContextHandler that recognizes managedObject of type %s.", managedObject);
+ throw _Exceptions.unrecoverable(msg);
+ }
+
+ val uri = resolver.identifierOf(managedObject);
+
+ return uri;
+
+ }
+
+ @Override
+ public Instance<ManagedObject> resolve(ObjectSpecId spec, URI identifier) {
+
+ requires(identifier, "identifier");
+
+ val instance = contextHandlers.stream()
+ .filter(handler->handler.recognizes(identifier))
+ .findFirst()
+ .map(handler->handler.resolve(spec, identifier))
+ .orElseThrow(()->{
+ val msg = String.format(
+ "Could not find a ContextHandler that recognizes identifier URI %s.", identifier);
+ return _Exceptions.unrecoverable(msg);
+ });
+
+ return instance;
+ }
+
+ @Override
+ public ManagedObjectResolver resolverFor(ObjectSpecification objSpec) {
+
+ requires(objSpec, "objSpec");
+
+ return contextHandlers.stream()
+ .filter(handler->handler.recognizes(objSpec))
+ .findFirst()
+ .orElse(null);
+ }
+
+
+
+
+}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java
index d74b22a..104b406 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/adapter/PojoAdapter.java
@@ -21,10 +21,8 @@ package org.apache.isis.core.runtime.persistence.adapter;
import static org.apache.isis.commons.internal.base._With.requires;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import org.apache.isis.commons.internal.base._Lazy;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.commons.exceptions.IsisException;
import org.apache.isis.core.commons.util.ToString;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
@@ -32,12 +30,15 @@ import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
import org.apache.isis.core.metamodel.adapter.oid.Oid;
import org.apache.isis.core.metamodel.adapter.oid.ParentedOid;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.adapter.oid.UniversalOid;
import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
import org.apache.isis.core.metamodel.adapter.version.Version;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
import org.apache.isis.core.security.authentication.AuthenticationSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public final class PojoAdapter implements ObjectAdapter {
@@ -113,6 +114,11 @@ public final class PojoAdapter implements ObjectAdapter {
@Override
public boolean isTransient() {
+
+ if(oid instanceof UniversalOid) {
+ return oid.isTransient(); //FIXME [2033] this is a quick-hack
+ }
+
if(getSpecification().isService() || getSpecification().isViewModel()) {
// services and view models are treated as persistent objects
return false;
@@ -122,6 +128,11 @@ public final class PojoAdapter implements ObjectAdapter {
@Override
public boolean representsPersistent() {
+
+ if(oid instanceof UniversalOid) {
+ return oid.isPersistent(); //FIXME [2033] this is a quick-hack
+ }
+
if(getSpecification().isService() || getSpecification().isViewModel()) {
// services and view models are treated as persistent objects
return true;
@@ -131,6 +142,11 @@ public final class PojoAdapter implements ObjectAdapter {
@Override
public boolean isDestroyed() {
+
+ if(oid instanceof UniversalOid) {
+ return false; //FIXME [2033] this is a quick-hack
+ }
+
if(getSpecification().isService() || getSpecification().isViewModel()) {
// services and view models are treated as persistent objects
return false;
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
index 6d78ee1..134931c 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
@@ -40,7 +40,9 @@ import org.apache.isis.core.metamodel.spec.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;
+import org.apache.isis.core.runtime.contextmanger.ContextManager;
import org.apache.isis.core.runtime.memento.Data;
+import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
import org.apache.isis.core.security.authentication.AuthenticationSession;
@@ -76,6 +78,7 @@ final public class ObjectAdapterContext {
final ObjectAdapterContext_ObjectCreation objectCreationMixin;
private final ObjectAdapterContext_LifecycleEventSupport lifecycleEventMixin;
private final ServiceInjector servicesInjector;
+ final ContextManager contextManager;
private ObjectAdapterContext(
ServiceInjector servicesInjector,
@@ -89,7 +92,10 @@ final public class ObjectAdapterContext {
this.mementoSupportMixin = new ObjectAdapterContext_MementoSupport(this, persistenceSession);
this.serviceLookupMixin = new ObjectAdapterContext_ServiceLookup(this, servicesInjector);
this.newIdentifierMixin = new ObjectAdapterContext_NewIdentifier(this, metaModelContext, persistenceSession);
- this.objectAdapterByIdProviderMixin = new ObjectAdapterContext_ObjectAdapterByIdProvider(this, metaModelContext, persistenceSession, authenticationSession);
+
+ this.contextManager = IsisContext.getServiceRegistry().lookupServiceElseFail(ContextManager.class);
+
+ this.objectAdapterByIdProviderMixin = new ObjectAdapterContext_ObjectAdapterByIdProvider(this, contextManager, metaModelContext, persistenceSession, authenticationSession);
this.dependencyInjectionMixin = new ObjectAdapterContext_DependencyInjection(this, persistenceSession);
this.objectCreationMixin = new ObjectAdapterContext_ObjectCreation(this, metaModelContext, persistenceSession);
this.lifecycleEventMixin = new ObjectAdapterContext_LifecycleEventSupport(this, metaModelContext, persistenceSession);
@@ -102,6 +108,8 @@ final public class ObjectAdapterContext {
authenticationSession,
specificationLoader,
persistenceSession);
+
+
}
// -- DEBUG
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterByIdProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterByIdProvider.java
index 5add0ce..9606686 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterByIdProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterByIdProvider.java
@@ -20,13 +20,12 @@ package org.apache.isis.core.runtime.system.persistence.adaptermanager;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.stream.Stream;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import org.apache.isis.commons.internal.collections._Lists;
import org.apache.isis.commons.internal.collections._Maps;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.commons.ensure.Ensure;
import org.apache.isis.core.metamodel.MetaModelContext;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
@@ -34,15 +33,21 @@ import org.apache.isis.core.metamodel.adapter.ObjectAdapterByIdProvider;
import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
import org.apache.isis.core.metamodel.adapter.oid.Oid;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.adapter.oid.UniversalOid;
import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
import org.apache.isis.core.metamodel.adapter.version.Version;
import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
+import org.apache.isis.core.runtime.contextmanger.ContextManager;
import org.apache.isis.core.runtime.persistence.ObjectNotFoundException;
import org.apache.isis.core.runtime.persistence.PojoRecreationException;
import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
import org.apache.isis.core.security.authentication.AuthenticationSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import lombok.val;
/**
* package private mixin for ObjectAdapterContext
@@ -59,18 +64,23 @@ class ObjectAdapterContext_ObjectAdapterByIdProvider implements ObjectAdapterByI
private final PersistenceSession persistenceSession;
private final SpecificationLoader specificationLoader;
private final AuthenticationSession authenticationSession;
+ private final ContextManager contextManager;
private final boolean concurrencyCheckingGloballyEnabled;
ObjectAdapterContext_ObjectAdapterByIdProvider(
ObjectAdapterContext objectAdapterContext,
+ ContextManager contextManager,
MetaModelContext metaModelContext,
PersistenceSession persistenceSession,
AuthenticationSession authenticationSession) {
+ Objects.requireNonNull(contextManager);
+
this.objectAdapterContext = objectAdapterContext;
this.persistenceSession = persistenceSession;
this.specificationLoader = metaModelContext.getSpecificationLoader();
this.authenticationSession = authenticationSession;
+ this.contextManager = contextManager;
this.concurrencyCheckingGloballyEnabled =
!ConcurrencyChecking.isGloballyDisabled(persistenceSession.getConfiguration());
@@ -108,7 +118,7 @@ class ObjectAdapterContext_ObjectAdapterByIdProvider implements ObjectAdapterByI
final RootOid rootOid,
final ConcurrencyChecking concurrencyChecking) {
- /* FIXME[ISIS-1976] SPI for adapterFor(RootOid)
+ /* FIXME [ISIS-1976] SPI for adapterFor(RootOid)
* https://github.com/apache/isis/pull/121#discussion_r215889748
*
* Eventually I'm hoping that this code will simplify and then become pluggable.
@@ -125,8 +135,33 @@ class ObjectAdapterContext_ObjectAdapterByIdProvider implements ObjectAdapterByI
* into some other datastore. So really my "PersistenceProvider" is a
* generalization of that concept).
*/
-
- //FIXME[ISIS-1976] remove guard
+
+ if(rootOid instanceof UniversalOid) {
+
+ Objects.requireNonNull(rootOid);
+
+ val universalOid = (UniversalOid) rootOid;
+ val spec = universalOid.getObjectSpecId();
+ val instance = contextManager.resolve(spec, universalOid.universalId());
+
+ if(instance.isResolvable()) {
+ val managedObject = instance.get();
+ return objectAdapterContext.getFactories().createRootAdapter(managedObject.getPojo(), rootOid);
+ } else if(instance.isAmbiguous()) {
+
+ //FIXME [2033] handle ambiguity
+ throw _Exceptions.notImplemented();
+
+ } else {
+
+ //FIXME [2033] handle no such element
+ throw _Exceptions.notImplemented();
+ }
+
+
+ }
+
+ //FIXME [ISIS-1976] remove guard
final ObjectAdapter serviceAdapter = objectAdapterContext.lookupServiceAdapterFor(rootOid);
if (serviceAdapter != null) {
//throw _Exceptions.unexpectedCodeReach();
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
index 90ea7d7..b829ddb 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
@@ -35,6 +35,7 @@ import org.apache.isis.core.metamodel.MetaModelContext;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.adapter.oid.UniversalOid;
import org.apache.isis.core.metamodel.services.ServiceUtil;
import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@@ -72,8 +73,8 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
this.oidFactory = OidFactory.builder(pojo->specificationLoader.loadSpecification(pojo.getClass()))
.add(new ObjectAdapterContext_OidProviders.GuardAgainstRootOid())
+ .add(new ObjectAdapterContext_OidProviders.OidForManagedContexts())
.add(new ObjectAdapterContext_OidProviders.OidForServices())
- .add(new ObjectAdapterContext_OidProviders.OidForManagedBeans())
.add(new ObjectAdapterContext_OidProviders.OidForValues())
.add(new ObjectAdapterContext_OidProviders.OidForViewModels())
.add(new ObjectAdapterContext_OidProviders.OidForPersistent())
@@ -88,10 +89,13 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
return null;
}
- //FIXME [2033] the pojo might be a managed object (eg. by Spring or CDI), this is new
-
final RootOid rootOid = oidFactory.oidFor(pojo);
final ObjectAdapter newAdapter = objectAdapterContext.getFactories().createRootAdapter(pojo, rootOid);
+
+ // the pojo might be a managed object (eg. by Spring or CDI), this is new
+ if(rootOid instanceof UniversalOid) {
+ return newAdapter; // skip service injection
+ }
return objectAdapterContext.injectServices(newAdapter);
}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_OidProviders.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_OidProviders.java
index 4421f59..699b4d6 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_OidProviders.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_OidProviders.java
@@ -18,19 +18,19 @@
*/
package org.apache.isis.core.runtime.system.persistence.adaptermanager;
-import java.lang.reflect.InvocationTargetException;
+import java.util.Objects;
import java.util.UUID;
-import javax.persistence.Entity;
-
-import org.apache.isis.commons.internal._Constants;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.commons.internal.base._Lazy;
+import org.apache.isis.commons.internal.base._Tuples;
import org.apache.isis.core.metamodel.IsisJdoMetamodelPlugin;
import org.apache.isis.core.metamodel.adapter.oid.Oid;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.runtime.contextmanger.ContextManager;
+import org.apache.isis.core.runtime.contextmanger.ManagedObjectResolver;
import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
import org.apache.isis.core.runtime.system.persistence.adaptermanager.factories.OidFactory.OidProvider;
@@ -43,31 +43,30 @@ class ObjectAdapterContext_OidProviders {
static class GuardAgainstRootOid implements OidProvider {
@Override
- public boolean isHandling(Object pojo, ObjectSpecification spec) {
- return pojo instanceof RootOid;
+ public boolean isHandling(ManagedObject managedObject) {
+ return managedObject.getPojo() instanceof RootOid;
}
@Override
- public RootOid oidFor(Object pojo, ObjectSpecification spec) {
+ public RootOid oidFor(ManagedObject managedObject) {
throw new IllegalArgumentException("Cannot create a RootOid for pojo, "
+ "when pojo is instance of RootOid. You might want to ask "
+ "ObjectAdapterByIdProvider for an ObjectAdapter instead.");
}
-
}
static class OidForServices implements OidProvider {
@Override
- public boolean isHandling(Object pojo, ObjectSpecification spec) {
- return spec.isService();
+ public boolean isHandling(ManagedObject managedObject) {
+ return managedObject.getSpecification().isService();
}
@Override
- public RootOid oidFor(Object pojo, ObjectSpecification spec) {
+ public RootOid oidFor(ManagedObject managedObject) {
final String identifier = PersistenceSession.SERVICE_IDENTIFIER;
- return Oid.Factory.persistentOf(spec.getSpecId(), identifier);
+ return Oid.Factory.persistentOf(managedObject.getSpecification().getSpecId(), identifier);
}
}
@@ -77,14 +76,18 @@ class ObjectAdapterContext_OidProviders {
private final IsisJdoMetamodelPlugin isisJdoMetamodelPlugin = IsisJdoMetamodelPlugin.get();
@Override
- public boolean isHandling(Object pojo, ObjectSpecification spec) {
+ public boolean isHandling(ManagedObject managedObject) {
// equivalent to 'isInstanceOfPersistable = pojo instanceof Persistable'
- final boolean isInstanceOfPersistable = isisJdoMetamodelPlugin.isPersistenceEnhanced(pojo.getClass());
+ final boolean isInstanceOfPersistable = isisJdoMetamodelPlugin
+ .isPersistenceEnhanced(managedObject.getPojo().getClass());
return isInstanceOfPersistable;
}
@Override
- public RootOid oidFor(Object pojo, ObjectSpecification spec) {
+ public RootOid oidFor(ManagedObject managedObject) {
+ val pojo = managedObject.getPojo();
+ val spec = managedObject.getSpecification();
+
final PersistenceSession persistenceSession = IsisContext.getPersistenceSession().get();
final boolean isRecognized = persistenceSession.isRecognized(pojo);
if(isRecognized) {
@@ -98,38 +101,40 @@ class ObjectAdapterContext_OidProviders {
}
- static class OidForManagedBeans implements OidProvider {
+ static class OidForManagedContexts implements OidProvider {
- //FIXME [2033] this is just a PoC for 'Customer'
+ final _Lazy<ContextManager> contextManager = _Lazy.of(()->
+ IsisContext.getServiceRegistry().lookupServiceElseFail(ContextManager.class));
+
+ private _Tuples.Tuple2<Object, ManagedObjectResolver> latestLookup; // acts as a cache
@Override
- public boolean isHandling(Object pojo, ObjectSpecification spec) {
- return pojo.getClass().isAnnotationPresent(Entity.class);
+ public boolean isHandling(ManagedObject managedObject) {
+ val pojo = managedObject.getPojo();
+ val spec = managedObject.getSpecification();
+
+ val managedObjectResolver = contextManager.get().resolverFor(spec);
+
+ if(managedObjectResolver!=null) {
+ // likely to be reused below, just an optimization
+ latestLookup = _Tuples.pair(pojo, managedObjectResolver);
+ return true;
+ }
+ return false;
}
@Override
- public RootOid oidFor(Object pojo, ObjectSpecification spec) {
- try {
- return oidForCustomer(pojo, spec);
- } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
- | InvocationTargetException e) {
- throw _Exceptions.unrecoverable(e);
- }
- }
-
- private RootOid oidForCustomer(Object pojo, ObjectSpecification spec)
- throws NoSuchMethodException, SecurityException, IllegalAccessException,
- IllegalArgumentException, InvocationTargetException {
-
- val idGetter = pojo.getClass().getMethod("getId", _Constants.emptyClasses);
- Long id = (Long)idGetter.invoke(pojo, _Constants.emptyObjects);
- if(id!=null && id>0) {
- final String identifier = "" + id;
- return Oid.Factory.persistentOf(spec.getSpecId(), identifier);
- } else {
- final String identifier = UUID.randomUUID().toString();
- return Oid.Factory.transientOf(spec.getSpecId(), identifier);
- }
+ public RootOid oidFor(ManagedObject managedObject) {
+ val pojo = managedObject.getPojo();
+ val spec = managedObject.getSpecification();
+
+ val managedObjectResolver = (latestLookup!=null &&
+ Objects.equals(pojo, latestLookup.get_1()))
+ ? latestLookup.get_2() // use cache
+ : contextManager.get().resolverFor(spec);
+
+ val objectIdUri = managedObjectResolver.identifierOf(managedObject);
+ return Oid.Factory.universal(objectIdUri);
}
}
@@ -137,12 +142,13 @@ class ObjectAdapterContext_OidProviders {
static class OidForValues implements OidProvider {
@Override
- public boolean isHandling(Object pojo, ObjectSpecification spec) {
+ public boolean isHandling(ManagedObject managedObject) {
+ val spec = managedObject.getSpecification();
return spec.containsFacet(ValueFacet.class);
}
@Override
- public RootOid oidFor(Object pojo, ObjectSpecification spec) {
+ public RootOid oidFor(ManagedObject managedObject) {
return Oid.Factory.value();
}
@@ -151,12 +157,16 @@ class ObjectAdapterContext_OidProviders {
static class OidForViewModels implements OidProvider {
@Override
- public boolean isHandling(Object pojo, ObjectSpecification spec) {
+ public boolean isHandling(ManagedObject managedObject) {
+ val spec = managedObject.getSpecification();
return spec.containsFacet(ViewModelFacet.class);
}
@Override
- public RootOid oidFor(Object pojo, ObjectSpecification spec) {
+ public RootOid oidFor(ManagedObject managedObject) {
+ val pojo = managedObject.getPojo();
+ val spec = managedObject.getSpecification();
+
final ViewModelFacet recreatableObjectFacet = spec.getFacet(ViewModelFacet.class);
final String identifier = recreatableObjectFacet.memento(pojo);
return Oid.Factory.viewmodelOf(spec.getSpecId(), identifier);
@@ -167,12 +177,13 @@ class ObjectAdapterContext_OidProviders {
static class OidForOthers implements OidProvider {
@Override
- public boolean isHandling(Object pojo, ObjectSpecification spec) {
+ public boolean isHandling(ManagedObject managedObject) {
return true; // try to handle anything
}
@Override
- public RootOid oidFor(Object pojo, ObjectSpecification spec) {
+ public RootOid oidFor(ManagedObject managedObject) {
+ val spec = managedObject.getSpecification();
final String identifier = UUID.randomUUID().toString();
return Oid.Factory.transientOf(spec.getSpecId(), identifier);
}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/factories/OidFactory.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/factories/OidFactory.java
index d3646ae..3b34eb7 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/factories/OidFactory.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/factories/OidFactory.java
@@ -22,6 +22,7 @@ package org.apache.isis.core.runtime.system.persistence.adaptermanager.factories
import java.util.function.Function;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
/**
@@ -32,8 +33,8 @@ public interface OidFactory {
RootOid oidFor(Object pojo);
public interface OidProvider {
- boolean isHandling(Object pojo, ObjectSpecification spec);
- RootOid oidFor(Object pojo, ObjectSpecification spec);
+ boolean isHandling(ManagedObject managedObject);
+ RootOid oidFor(ManagedObject managedObject);
}
public interface OidFactoryBuilder {
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/factories/OidFactory_Builder.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/factories/OidFactory_Builder.java
index 4f4e46a..fab1201 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/factories/OidFactory_Builder.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/factories/OidFactory_Builder.java
@@ -19,16 +19,20 @@
package org.apache.isis.core.runtime.system.persistence.adaptermanager.factories;
+import static java.util.Objects.requireNonNull;
+
import java.util.ArrayList;
import java.util.List;
-import java.util.Objects;
import java.util.function.Function;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.spec.ManagedObject.SimpleManagedObject;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.runtime.system.persistence.adaptermanager.factories.OidFactory.OidFactoryBuilder;
import org.apache.isis.core.runtime.system.persistence.adaptermanager.factories.OidFactory.OidProvider;
+import lombok.val;
+
class OidFactory_Builder implements OidFactoryBuilder {
private final List<OidProvider> handler = new ArrayList<>();
@@ -49,14 +53,15 @@ class OidFactory_Builder implements OidFactoryBuilder {
return pojo -> {
final ObjectSpecification spec = specProvider.apply(pojo);
-
+ val managedObject = SimpleManagedObject.of(spec, pojo);
+
final RootOid rootOid = handler.stream()
- .filter(h->h.isHandling(pojo, spec))
+ .filter(h->h.isHandling(managedObject))
.findFirst()
- .map(h->h.oidFor(pojo, spec))
+ .map(h->h.oidFor(managedObject))
.orElse(null);
- Objects.requireNonNull(rootOid, () -> "Could not create an Oid for pojo: "+pojo);
+ requireNonNull(rootOid, () -> "Could not create an Oid for pojo: "+pojo);
return rootOid;
};
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionProducerBean.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionProducerBean.java
index 5cba4d2..e5c6171 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionProducerBean.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionProducerBean.java
@@ -29,14 +29,15 @@ import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory;
/**
- * @deprecated TODO [2033]
+ * @deprecated TODO [2033] convert ...
* Currently `IsisSessionFactory` and those singletons that depend on it
* (`SpecificationLoader` and `PersistenceSessionFactory`) are not life-cycle
* managed by CDI, instead we provide Producer Methods for these.
*
* Consequently the framework is responsible for their life-cycles.
*
- * We want to have CDI also manage these, which can be achieved by finally removing the `IsisSessionProducerBean` singleton.
+ * We want to have CDI also manage these, which can be achieved by finally
+ * removing the `IsisSessionProducerBean` singleton.
*
*/
@Singleton
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
index 0b4ba2b..f38350a 100644
--- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
@@ -253,7 +253,7 @@ implements ComponentFactoryRegistryAccessor, PageClassRegistryAccessor, WicketVi
new CdiConfiguration(beanManager).configure(this);
-// // FIXME [2033]
+// // FIXME [2033] remove comments ...
// // create IsisSessionFactory
// //
// final Injector injector = Guice.createInjector(
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/ConverterForObjectAdapterMemento.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/ConverterForObjectAdapterMemento.java
index 6b62d8d..f944f15 100644
--- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/ConverterForObjectAdapterMemento.java
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/ConverterForObjectAdapterMemento.java
@@ -56,7 +56,7 @@ public class ConverterForObjectAdapterMemento implements IConverter<ObjectAdapte
final RootOid oid = RootOid.deStringEncoded(value);
final ObjectAdapter adapter = getPersistenceSession().adapterFor(oid);
- return ObjectAdapterMemento.createOrNull(adapter);
+ return ObjectAdapterMemento.mementoOf(adapter);
}
/**
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java
index 66c315b..1ed2992 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java
@@ -20,14 +20,18 @@
package org.apache.isis.viewer.wicket.model.mementos;
import java.io.Serializable;
+import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
+import javax.annotation.Nullable;
+
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.applib.services.hint.HintStore;
import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.uri._URI;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
@@ -44,6 +48,8 @@ import org.apache.isis.core.runtime.memento.Memento;
import org.apache.isis.core.runtime.persistence.ObjectNotFoundException;
import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+import lombok.val;
+
public class ObjectAdapterMemento implements Serializable {
private static final long serialVersionUID = 1L;
@@ -51,7 +57,7 @@ public class ObjectAdapterMemento implements Serializable {
/**
* Factory method
*/
- public static ObjectAdapterMemento createOrNull(final ObjectAdapter adapter) {
+ public static ObjectAdapterMemento mementoOf(@Nullable final ObjectAdapter adapter) {
if (adapter == null) {
return null;
}
@@ -226,6 +232,14 @@ public class ObjectAdapterMemento implements Serializable {
final ObjectAdapterMemento oam,
ConcurrencyChecking concurrencyChecking,
final PersistenceSession persistenceSession, final SpecificationLoader specificationLoader) {
+
+ if(_URI.isUoid(oam.persistentOidStr)) {
+ val uri = URI.create(oam.persistentOidStr);
+ val oid = Oid.Factory.universal(uri);
+ val objAdapter = persistenceSession.adapterFor(oid, concurrencyChecking);
+ return objAdapter;
+ }
+
RootOid oid = Oid.unmarshaller().unmarshal(oam.persistentOidStr, RootOid.class);
try {
final ObjectAdapter adapter = persistenceSession.adapterFor(oid, concurrencyChecking);
@@ -573,11 +587,11 @@ public class ObjectAdapterMemento implements Serializable {
}
public static Function<Object, ObjectAdapterMemento> fromPojo(final ObjectAdapterProvider adapterProvider) {
- return pojo->ObjectAdapterMemento.createOrNull( adapterProvider.adapterFor(pojo) );
+ return pojo->ObjectAdapterMemento.mementoOf( adapterProvider.adapterFor(pojo) );
}
public static Function<ObjectAdapter, ObjectAdapterMemento> fromAdapter() {
- return ObjectAdapterMemento::createOrNull;
+ return ObjectAdapterMemento::mementoOf;
}
public static Function<ObjectAdapterMemento, ObjectAdapter> fromMemento(
@@ -596,7 +610,7 @@ public class ObjectAdapterMemento implements Serializable {
}
public static Function<ObjectAdapter, ObjectAdapterMemento> toMemento() {
- return ObjectAdapterMemento::createOrNull;
+ return ObjectAdapterMemento::mementoOf;
}
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
index f913940..8c7ddb9 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
@@ -488,7 +488,7 @@ UiHintContainer {
public void toggleSelectionOn(ObjectAdapter selectedAdapter) {
- ObjectAdapterMemento selectedAsMemento = ObjectAdapterMemento.createOrNull(selectedAdapter);
+ ObjectAdapterMemento selectedAsMemento = ObjectAdapterMemento.mementoOf(selectedAdapter);
// try to remove; if couldn't, then mustn't have been in there, in which case add.
boolean removed = toggledMementosList.remove(selectedAsMemento);
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
index 4235404..8e27759 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
@@ -177,7 +177,7 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> implements Obj
}
public EntityModel(final ObjectAdapter adapter) {
- this(ObjectAdapterMemento.createOrNull(adapter));
+ this(ObjectAdapterMemento.mementoOf(adapter));
setObject(adapter);
}
@@ -356,7 +356,7 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> implements Obj
@Override
public void setObject(final ObjectAdapter adapter) {
super.setObject(adapter);
- adapterMemento = ObjectAdapterMemento.createOrNull(adapter);
+ adapterMemento = ObjectAdapterMemento.mementoOf(adapter);
}
public void setObjectMemento(
@@ -532,7 +532,7 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> implements Obj
return pending;
}
final ObjectAdapter adapter = entityModel.getObject();
- return ObjectAdapterMemento.createOrNull(adapter);
+ return ObjectAdapterMemento.mementoOf(adapter);
}
@Override
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModelForReference.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModelForReference.java
index 6110b73..f4610ab 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModelForReference.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModelForReference.java
@@ -91,7 +91,7 @@ public class EntityModelForReference implements ObjectAdapterModel {
@Override
public PageParameters getPageParameters() {
PageParameters pageParameters = createPageParameters(getObject());
- ObjectAdapterMemento oam = ObjectAdapterMemento.createOrNull(getObject());
+ ObjectAdapterMemento oam = ObjectAdapterMemento.mementoOf(getObject());
HintPageParameterSerializer.hintStoreToPageParameters(pageParameters, oam);
return pageParameters;
}
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ValueModel.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ValueModel.java
index 2f4698e..ca05d5e 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ValueModel.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ValueModel.java
@@ -34,7 +34,7 @@ public class ValueModel extends ModelAbstract<ObjectAdapter> {
private final ObjectAdapterMemento adapterMemento;
public ValueModel(final ObjectAdapter adapter) {
- adapterMemento = ObjectAdapterMemento.createOrNull(adapter);
+ adapterMemento = ObjectAdapterMemento.mementoOf(adapter);
}
@Override
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/EntityActionLinkFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/EntityActionLinkFactory.java
index 2a33d13..cdd7423 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/EntityActionLinkFactory.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/EntityActionLinkFactory.java
@@ -48,7 +48,7 @@ public final class EntityActionLinkFactory extends ActionLinkFactoryAbstract {
final ObjectAdapter objectAdapter = this.targetEntityModel.load(ConcurrencyChecking.NO_CHECK);
- final Boolean persistent = objectAdapter.representsPersistent();
+ final boolean persistent = objectAdapter.representsPersistent();
if (!persistent) {
throw new IllegalArgumentException(String.format(
"Object '%s' is not persistent.", objectAdapter.titleString(null)));
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java
index 49d3eef..59ee34b 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java
@@ -19,6 +19,7 @@ package org.apache.isis.viewer.wicket.ui.panels;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Callable;
+import java.util.function.BiFunction;
import java.util.stream.Stream;
import org.apache.isis.applib.RecoverableException;
@@ -30,9 +31,12 @@ import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerComposite;
import org.apache.isis.applib.services.hint.HintStore;
import org.apache.isis.applib.services.message.MessageService;
import org.apache.isis.applib.services.registry.ServiceRegistry;
+import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.commons.internal.collections._Lists;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+import org.apache.isis.core.metamodel.adapter.oid.UniversalOid;
import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
import org.apache.isis.core.metamodel.facets.actions.redirect.RedirectFacet;
import org.apache.isis.core.metamodel.facets.properties.renderunchanged.UnchangingFacet;
@@ -68,6 +72,8 @@ import org.slf4j.LoggerFactory;
import com.google.common.base.Throwables;
+import lombok.val;
+
public final class FormExecutorDefault<M extends BookmarkableModel<ObjectAdapter> & ParentEntityModelProvider>
implements FormExecutor {
@@ -279,10 +285,24 @@ implements FormExecutor {
final ObjectAdapter targetAdapter,
final ObjectAdapter resultAdapter) {
- final ObjectAdapterMemento targetOam = ObjectAdapterMemento.createOrNull(targetAdapter);
- final ObjectAdapterMemento resultOam = ObjectAdapterMemento.createOrNull(resultAdapter);
-
- return differs(targetOam, resultOam);
+ val left = targetAdapter.getOid();
+ val right = resultAdapter.getOid();
+
+ val differs = _Casts.castThenApply(left, right, UniversalOid.class,
+ (l, r)-> !Objects.equals(l, r), // onBothCast
+ (l, r) -> true, // onLeftCast
+ (l, r) -> true, // onRightCast
+ (l, r) -> { // onNonCast
+
+ // legacy behavior, for non UniversalOid
+
+ final ObjectAdapterMemento targetOam = ObjectAdapterMemento.mementoOf(targetAdapter);
+ final ObjectAdapterMemento resultOam = ObjectAdapterMemento.mementoOf(resultAdapter);
+
+ return differs(targetOam, resultOam);
+ });
+
+ return differs;
}
private static boolean differs(
diff --git a/example/application/simpleapp/application/src/main/java/domainapp/application/manifest/menubars.layout.xml b/example/application/simpleapp/application/src/main/java/domainapp/application/manifest/menubars.layout.xml
index d286f2d..9846d45 100644
--- a/example/application/simpleapp/application/src/main/java/domainapp/application/manifest/menubars.layout.xml
+++ b/example/application/simpleapp/application/src/main/java/domainapp/application/manifest/menubars.layout.xml
@@ -33,6 +33,19 @@
</mb3:serviceAction>
</mb3:section>
</mb3:menu>
+
+ </mb3:menu>
+ <mb3:named>Spring</mb3:named>
+ <mb3:section>
+ <mb3:serviceAction objectType="simple.CustomerMenu" id="createCustomer">
+ <cpt:named>Create Customer</cpt:named>
+ </mb3:serviceAction>
+ <mb3:serviceAction objectType="simple.CustomerMenu" id="findByLastName">
+ <cpt:named>Find By Last Name</cpt:named>
+ </mb3:serviceAction>
+ </mb3:section>
+ </mb3:menu>
+
<mb3:menu unreferencedActions="true">
<mb3:named>Other</mb3:named>
</mb3:menu>
diff --git a/example/application/simpleapp/module-spring/src/main/java/domainapp/modules/spring/SpringDataJPADemoHandler.java b/example/application/simpleapp/module-spring/src/main/java/domainapp/modules/spring/SpringDataJPADemoHandler.java
new file mode 100644
index 0000000..f2a0cdd
--- /dev/null
+++ b/example/application/simpleapp/module-spring/src/main/java/domainapp/modules/spring/SpringDataJPADemoHandler.java
@@ -0,0 +1,100 @@
+package domainapp.modules.spring;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+import java.util.UUID;
+
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.persistence.Entity;
+import javax.persistence.EntityManager;
+
+import org.apache.isis.commons.internal._Constants;
+import org.apache.isis.commons.internal.cdi._CDI;
+import org.apache.isis.commons.internal.debug._Probe;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.commons.internal.uri._URI;
+import org.apache.isis.commons.internal.uri._URI.ContainerType;
+import org.apache.isis.commons.internal.uri._URI.ContextType;
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.ManagedObject.SimpleManagedObject;
+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.contextmanger.ContextHandler;
+import org.springframework.context.ApplicationContext;
+
+import domainapp.modules.spring.dom.customer.Customer;
+import lombok.val;
+
+@Singleton
+public class SpringDataJPADemoHandler implements ContextHandler {
+
+ private final static _Probe probe = _Probe.unlimited().label("SpringDataJPADemoHandler");
+
+ @Inject ApplicationContext springContext;
+ @Inject SpecificationLoader specLoader;
+
+ @Override
+ public URI identifierOf(ManagedObject managedObject) {
+ try {
+ return identifierForCustomer(managedObject.getPojo(), managedObject.getSpecification());
+ } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
+ | InvocationTargetException e) {
+ throw _Exceptions.unrecoverable(e);
+ }
+ }
+
+ @Override
+ public Instance<ManagedObject> resolve(ObjectSpecId specId, URI identifier) {
+
+ // FIXME [2033] this is just a PoC
+
+ long id = Long.parseLong(identifier.getQuery());
+
+ val em = springContext.getBean(EntityManager.class);
+
+ val customer = em.find(Customer.class, id);
+ val spec = specLoader.lookupBySpecId(specId);
+
+ val managedObject = SimpleManagedObject.of(spec, customer);
+
+ return _CDI.InstanceFactory.singleton(managedObject);
+ }
+
+ @Override
+ public boolean recognizes(URI uri) {
+ return uri.toString().startsWith("uoid://entities@spring");
+ }
+
+ @Override
+ public boolean recognizes(ObjectSpecification objSpec) {
+ // FIXME [2033] this is just a PoC
+ return objSpec.getCorrespondingClass().isAnnotationPresent(Entity.class);
+ }
+
+ // -- HELPER
+
+ private URI identifierForCustomer(Object pojo, ObjectSpecification spec)
+ throws NoSuchMethodException, SecurityException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException {
+
+ val idGetter = pojo.getClass().getMethod("getId", _Constants.emptyClasses);
+ final Long id = (Long)idGetter.invoke(pojo, _Constants.emptyObjects);
+ final String identifier = (id!=null && id>0)
+ ? "" + id
+ : UUID.randomUUID().toString();
+
+ return _URI.uoidBuilder()
+ .containerType(ContainerType.spring)
+ .contextType(ContextType.entities)
+ .contextId(null)
+ .path("/"+spec.getSpecId().asString()+"/")
+ .query(identifier)
+ .build()
+ .toURI();
+ }
+
+
+}