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/02/11 14:08:12 UTC
[isis] branch 2033-IoC updated: ISIS-2033: adds new ContextManager
to handle ViewModels
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 ba46bce ISIS-2033: adds new ContextManager to handle ViewModels
ba46bce is described below
commit ba46bce12f2a8835bd7d83863211f80edb9af26c
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Feb 11 15:08:02 2019 +0100
ISIS-2033: adds new ContextManager to handle ViewModels
Task-Url: https://issues.apache.org/jira/browse/ISIS-2033
---
.../org/apache/isis/commons/internal/uri/_URI.java | 1 +
.../context/managers/AuthorityDescriptor.java | 38 ++++--
.../system/context/managers/Converters.java | 2 +-
.../context/managers/UniversalContextManager.java | 2 +-
.../context/managers/cdi/CDIContextManager.java | 20 ++-
.../viewmodel/ViewModelContextManager.java | 147 +++++++++++++++++++++
.../ObjectAdapterContext_OidProviders.java | 1 +
7 files changed, 193 insertions(+), 18 deletions(-)
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
index a52297c..b8ad5ff 100644
--- 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
@@ -90,6 +90,7 @@ public final class _URI {
}
public static enum ContainerType {
+ isis,
jdo,
cdi,
spring,
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/AuthorityDescriptor.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/AuthorityDescriptor.java
index 54e358d..850706a 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/AuthorityDescriptor.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/AuthorityDescriptor.java
@@ -10,14 +10,15 @@ import org.apache.isis.commons.internal.uri._URI.ContextType;
import org.apache.isis.commons.internal.uri._URI.UoidDto.UoidDtoBuilder;
import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import lombok.EqualsAndHashCode;
import lombok.Getter;
-import lombok.Value;
-import lombok.val;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
/**
* @since 2.0.0-M3
*/
-@Value(staticConstructor="of")
+@RequiredArgsConstructor(staticName="of") @ToString @EqualsAndHashCode
public final class AuthorityDescriptor {
@Getter private final ContainerType containerType;
@@ -34,16 +35,27 @@ public final class AuthorityDescriptor {
}
public boolean matches(URI uri) {
-
- val prefix = String.format("uoid://%s@%s%s/",
- containerType.name(),
- contextType.name(),
- isEmpty(contextId)
- ? "" :
- ":" + contextId
- );
-
- return uri.toString().startsWith(prefix);
+ if(uri==null) {
+ return false;
+ }
+ return uri.toString().startsWith(matchingPrefix());
+ }
+
+ // -- HELPER
+
+ private String matchingPrefix;
+
+ private String matchingPrefix() {
+ if(matchingPrefix==null) {
+ matchingPrefix = String.format("uoid://%s@%s%s/",
+ contextType.name(),
+ containerType.name(),
+ isEmpty(contextId)
+ ? "" :
+ ":" + contextId
+ );
+ }
+ return matchingPrefix;
}
}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/Converters.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/Converters.java
index b5a2fdd..476fcb2 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/Converters.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/Converters.java
@@ -32,7 +32,7 @@ public final class Converters {
public static interface FromUriConverter {
String encodeToString(@Nullable URI objectUri);
- String encodeToBase64(URI objectUri);
+ String encodeToBase64(@Nullable URI objectUri);
RootOid toRootOid(@Nullable URI objectUri);
}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/UniversalContextManager.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/UniversalContextManager.java
index e76359c..4276907 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/UniversalContextManager.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/UniversalContextManager.java
@@ -50,7 +50,7 @@ public class UniversalContextManager implements ContextManager {
.map(handler->handler.resolve(specId, identifier))
.orElseThrow(()->{
val msg = String.format(
- "Could not find a ContextHandler that recognizes identifier URI %s.", identifier);
+ "Could not find a ContextHandler that recognizes object URI '%s'.", identifier);
return _Exceptions.unrecoverable(msg);
});
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/cdi/CDIContextManager.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/cdi/CDIContextManager.java
index 8ca111d..1f3de27 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/cdi/CDIContextManager.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/cdi/CDIContextManager.java
@@ -63,11 +63,25 @@ public class CDIContextManager implements ContextHandler {
//TODO [2033] future extension ... to refine, convert id to array of Annotations
val qualifiers = _Constants.emptyAnnotations;
- val bean = serviceRegistry.getManagedBean(spec.getCorrespondingClass(), qualifiers);
+ val beanOptional = serviceRegistry.getManagedBean(spec.getCorrespondingClass(), qualifiers);
- val managedObject = SimpleManagedObject.of(spec, bean);
+ probe.println("resolve spec='%s' -> '%s'",
+ spec.getSpecId().asString(),
+ beanOptional);
+
+ if(beanOptional.isPresent()) {
+
+ val beanPojo = beanOptional.get();
+ val managedObject = SimpleManagedObject.of(spec, beanPojo);
+
+ return _CDI.InstanceFactory.singleton(managedObject);
+
+ }
+
+ // empty result
+
+ return _CDI.InstanceFactory.empty();
- return _CDI.InstanceFactory.singleton(managedObject);
}
@Override
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/viewmodel/ViewModelContextManager.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/viewmodel/ViewModelContextManager.java
new file mode 100644
index 0000000..098c416
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/managers/viewmodel/ViewModelContextManager.java
@@ -0,0 +1,147 @@
+package org.apache.isis.core.runtime.system.context.managers.viewmodel;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Modifier;
+import java.net.URI;
+import java.util.Optional;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.apache.isis.applib.services.inject.ServiceInjector;
+import org.apache.isis.commons.internal.cdi._CDI;
+import org.apache.isis.commons.internal.debug._Probe;
+import org.apache.isis.commons.internal.uri._URI.ContainerType;
+import org.apache.isis.commons.internal.uri._URI.ContextType;
+import org.apache.isis.core.commons.exceptions.IsisException;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
+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.system.context.managers.AuthorityDescriptor;
+import org.apache.isis.core.runtime.system.context.managers.ContextHandler;
+
+import lombok.val;
+
+/**
+ * @since 2.0.0-M3
+ */
+@Singleton
+public class ViewModelContextManager implements ContextHandler {
+
+ private final static _Probe probe = _Probe.unlimited().label("ViewModelContextManager");
+
+ @Inject SpecificationLoader specLoader;
+ @Inject ServiceInjector serviceInjector;
+
+ @PostConstruct
+ public void init() {
+ //
+ }
+
+ @Override
+ public URI uriOf(ManagedObject managedObject) {
+
+ val pojo = managedObject.getPojo();
+ val spec = managedObject.getSpecification();
+
+ val viewModelFacet = spec.getFacet(ViewModelFacet.class);
+ val serialized = viewModelFacet.memento(pojo);
+
+ probe.println("uriOf spec='%s', serialized='%s'",
+ spec.getSpecId().asString(),
+ serialized);
+
+ return DEFAULT_AUTHORITY.toUoidDtoBuilder(spec.getSpecId())
+ .query(serialized)
+ .build()
+ .toURI();
+ }
+
+ @Override
+ public Instance<ManagedObject> resolve(ObjectSpecId specId, URI objectUri) {
+
+ val serialized = objectUri.getQuery();
+ val spec = specLoader.lookupBySpecId(specId);
+
+ probe.println("resolve spec='%s', serialized='%s'",
+ spec.getSpecId().asString(),
+ serialized);
+
+ val viewModelPojo = deserializeViewModel(spec, serialized);
+
+ val managedObject = SimpleManagedObject.of(spec, viewModelPojo);
+
+ return _CDI.InstanceFactory.singleton(managedObject);
+ }
+
+ @Override
+ public boolean recognizes(ObjectSpecification spec) {
+ return spec.isViewModel();
+ }
+
+ @Override
+ public boolean recognizes(URI uri) {
+ return DEFAULT_AUTHORITY.matches(uri);
+ }
+
+ @Override
+ public Optional<AuthorityDescriptor> authorityFor(ObjectSpecification spec) {
+ if(!recognizes(spec)) {
+ return Optional.empty();
+ }
+ return Optional.of(DEFAULT_AUTHORITY);
+ }
+
+ // -- HELPER
+
+ private final static AuthorityDescriptor DEFAULT_AUTHORITY =
+ AuthorityDescriptor.of(ContainerType.isis, ContextType.beans, null);
+
+ private Object deserializeViewModel(final ObjectSpecification spec, final String serialized) {
+ final ViewModelFacet facet = spec.getFacet(ViewModelFacet.class);
+ if(facet == null) {
+ throw new IllegalArgumentException("spec does not have ViewModelFacet; spec is "
+ + spec.getFullIdentifier());
+ }
+
+ final Object viewModelPojo;
+ if(facet.getRecreationMechanism().isInitializes()) {
+ viewModelPojo = instantiateAndInjectServices(spec);
+ facet.initialize(viewModelPojo, serialized);
+ } else {
+ viewModelPojo = facet.instantiate(spec.getCorrespondingClass(), serialized);
+ }
+ return viewModelPojo;
+ }
+
+ private Object instantiateAndInjectServices(final ObjectSpecification objectSpec) {
+
+ final Class<?> correspondingClass = objectSpec.getCorrespondingClass();
+ if (correspondingClass.isArray()) {
+ return Array.newInstance(correspondingClass.getComponentType(), 0);
+ }
+
+ final Class<?> cls = correspondingClass;
+ if (Modifier.isAbstract(cls.getModifiers())) {
+ throw new IsisException("Cannot create an instance of an abstract class: " + cls);
+ }
+
+ final Object newInstance;
+ try {
+ newInstance = cls.newInstance();
+ } catch (final IllegalAccessException | InstantiationException e) {
+ throw new IsisException("Failed to create instance of type " + objectSpec.getFullIdentifier(), e);
+ }
+
+ serviceInjector.injectServicesInto(newInstance);
+ return newInstance;
+
+ }
+
+}
+
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 96f59fe..f12672c 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
@@ -158,6 +158,7 @@ class ObjectAdapterContext_OidProviders {
}
+ //TODO [2033] should no longer be required
static class OidForViewModels implements OidProvider {
@Override