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 2022/08/29 09:26:58 UTC
[isis] branch master updated: ISIS-3167: purge _ManagedObjectWithLazySpec
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new cefdf288ff ISIS-3167: purge _ManagedObjectWithLazySpec
cefdf288ff is described below
commit cefdf288ff58ce550c5db5dcd2529bb854b0779a
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Aug 29 11:26:50 2022 +0200
ISIS-3167: purge _ManagedObjectWithLazySpec
---
.../isis/core/metamodel/object/ManagedObject.java | 22 ------
.../object/_ManagedObjectWithLazySpec.java | 79 ----------------------
...entNegotiationServiceForRestfulObjectsV1_0.java | 11 ++-
.../JsonValueEncoderServiceDefault.java | 75 +++++++++++++-------
.../JsonValueEncoderTest_asAdapter.java | 31 +++++----
5 files changed, 75 insertions(+), 143 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java
index 17eca64550..41f3dadbba 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java
@@ -538,26 +538,4 @@ public interface ManagedObject extends HasMetaModelContext {
return _ManagedObjectWithEagerSpec.identified(spec, pojo, bookmark);
}
- /**
- * For cases, when the pojo's specification is not available and needs to be looked up.
- * @param specLoader
- * @param pojo
- */
- @Deprecated
- static ManagedObject lazy(
- final SpecificationLoader specLoader,
- final Object pojo) {
-
- if(pojo!=null) {
- _Assert.assertFalse(_Collections.isCollectionOrArrayOrCanType(pojo.getClass()));
- }
-
- ManagedObjects.assertPojoNotWrapped(pojo);
- val adapter = new _ManagedObjectWithLazySpec(cls->specLoader.specForType(cls).orElse(null), pojo);
- //ManagedObjects.warnIfAttachedEntity(adapter, "consider using ManagedObject.identified(...) for entity");
- return adapter;
- }
-
-
-
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithLazySpec.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithLazySpec.java
deleted file mode 100644
index 0ca4c35c08..0000000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithLazySpec.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.isis.core.metamodel.object;
-
-import java.util.function.Function;
-import java.util.function.UnaryOperator;
-
-import org.apache.isis.commons.internal.base._Lazy;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import lombok.NonNull;
-
-@Deprecated
-@EqualsAndHashCode(of = "pojo", callSuper = false)
-final class _ManagedObjectWithLazySpec
-extends _ManagedObjectWithBookmark {
-
- @NonNull private final Function<Class<?>, ObjectSpecification> specLoader;
-
- @Getter @NonNull private /*final*/ Object pojo;
-
- private final _Lazy<ObjectSpecification> specification = _Lazy.threadSafe(this::loadSpec);
-
- _ManagedObjectWithLazySpec(
- final @NonNull Function<Class<?>, ObjectSpecification> specLoader,
- final @NonNull Object pojo) {
- super(ManagedObject.Specialization.UNSPECIFIED); // FIXME
- this.specLoader = specLoader;
- this.pojo = pojo;
- }
-
- @Override
- public ObjectSpecification getSpecification() {
- return specification.get();
- }
-
- @Override //ISIS-2317 make sure toString() is without side-effects
- public String toString() {
- if(specification.isMemoized()) {
- return String.format("ManagedObject[spec=%s, pojo=%s]",
- ""+getSpecification(),
- ""+getPojo());
- }
- return String.format("ManagedObject[spec=%s, pojo=%s]",
- "[lazy not loaded]",
- ""+getPojo());
- }
-
- private ObjectSpecification loadSpec() {
- return specLoader.apply(pojo.getClass());
- }
-
- @Override
- public void replacePojo(final UnaryOperator<Object> replacer) {
- pojo = replacer.apply(pojo);
- if(specification.isMemoized()) {
- assertSpecIsInSyncWithPojo();
- }
- }
-
-}
\ No newline at end of file
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
index 53fde969e6..0a4ffd3d0b 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
@@ -213,11 +213,16 @@ implements ContentNegotiationService {
final ObjectSpecification actionOwnerSpec = actionOwnerSpecFrom(objectAndActionInvocation);
final String actionId = actionIdFrom(objectAndActionInvocation);
final String actionArguments = actionArgumentsFrom(objectAndActionInvocation);
- final DomainObjectList list = domainObjectListFrom(
+ final DomainObjectList listAsViewmodel = domainObjectListFrom(
collectionAdapters, elementSpec, actionOwnerSpec, actionId, actionArguments);
- val listAdapter = ManagedObject.lazy(
- resourceContext.getMetaModelContext().getSpecificationLoader(), list);
+ val domainObjectListSpec = resourceContext.getMetaModelContext().getSpecificationLoader()
+ .specForType(DomainObjectList.class)
+ .filter(ObjectSpecification::isViewModel)
+ .orElseThrow(()->_Exceptions.unrecoverable(
+ "framework bug: DomainObjectList should be recognized as viewmodel"));
+
+ val listAdapter = ManagedObject.viewmodel(domainObjectListSpec, listAsViewmodel);
return responseBuilder(
buildResponse(
resourceContext,
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/valuerender/JsonValueEncoderServiceDefault.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/valuerender/JsonValueEncoderServiceDefault.java
index 56d99bb1b4..65766b0270 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/valuerender/JsonValueEncoderServiceDefault.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/valuerender/JsonValueEncoderServiceDefault.java
@@ -33,10 +33,12 @@ import org.springframework.stereotype.Service;
import org.springframework.util.ClassUtils;
import org.apache.isis.applib.annotation.PriorityPrecedence;
-import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
import org.apache.isis.applib.value.semantics.ValueDecomposition;
+import org.apache.isis.commons.functional.Try;
import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.commons.internal.collections._Maps;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.core.metamodel.facets.object.value.ValueSerializer;
import org.apache.isis.core.metamodel.facets.object.value.ValueSerializer.Format;
import org.apache.isis.core.metamodel.object.ManagedObject;
import org.apache.isis.core.metamodel.object.ManagedObjects;
@@ -71,57 +73,80 @@ public class JsonValueEncoderServiceDefault implements JsonValueEncoderService {
@Override
public ManagedObject asAdapter(
- final ObjectSpecification objectSpec,
+ final ObjectSpecification spec,
final JsonRepresentation valueRepr,
final JsonValueConverter.Context context) {
if(valueRepr == null) {
return null;
}
- if (objectSpec == null) {
+ if (spec == null) {
throw new IllegalArgumentException("ObjectSpecification is required");
}
if (!valueRepr.isValue()) {
throw new IllegalArgumentException("Representation must be of a value");
}
- val valueClass = objectSpec.getCorrespondingClass();
+ val valueClass = spec.getCorrespondingClass();
val valueSerializer =
- Facets.valueSerializerElseFail(objectSpec, valueClass);
-
- final JsonValueConverter jvc = converterByClass.get(ClassUtils.resolvePrimitiveIfNecessary(valueClass));
- if(jvc == null) {
- // best effort
- if (valueRepr.isString()) {
- final String argStr = valueRepr.asString();
- return ManagedObject.of(objectSpec,
- valueSerializer.fromEncodedString(Format.JSON, argStr));
- }
- throw new IllegalArgumentException("Unable to parse value");
+ Facets.valueSerializerElseFail(spec, valueClass);
+
+ final JsonValueConverter jsonValueConverter = converterByClass
+ .get(ClassUtils.resolvePrimitiveIfNecessary(valueClass));
+ if(jsonValueConverter == null) {
+ // best effort: try 'String' type
+ return asStringElseFail(valueRepr, valueSerializer)
+ .map(string->ManagedObject.value(spec, string))
+ .orElseGet(()->ManagedObject.empty(spec));
}
- val valueAsPojo = jvc.recoverValueAsPojo(valueRepr, context);
+ val valueAsPojo = jsonValueConverter.recoverValueAsPojo(valueRepr, context);
if(valueAsPojo != null) {
- return ManagedObject.lazy(specificationLoader, valueAsPojo);
+ return ManagedObject.value(spec, valueAsPojo);
}
// last attempt
if (valueRepr.isString()) {
- final String argStr = valueRepr.asString();
- try {
- return ManagedObject.of(objectSpec,
- valueSerializer.fromEncodedString(Format.JSON, argStr));
- } catch(TextEntryParseException ex) {
- throw new IllegalArgumentException(ex.getMessage());
- }
+ return asStringElseFail(valueRepr, valueSerializer)
+ .map(string->ManagedObject.value(spec, string))
+ .orElseGet(()->ManagedObject.empty(spec));
}
throw new IllegalArgumentException("Could not parse value '"
+ valueRepr.asString()
+ "' as a "
- + objectSpec.getFullIdentifier());
+ + spec.getFullIdentifier());
+ }
+
+ /**
+ * Returns the recovered nullable String, wrapped as optional.
+ * @throws IllegalArgumentException if cannot be parsed as String
+ */
+ private static Optional<String> asStringElseFail(
+ final JsonRepresentation valueRepr,
+ final ValueSerializer<?> valueSerializer) {
+ if (valueRepr.isString()) {
+ val recoveredValue = Try.call(()->
+ valueSerializer.fromEncodedString(Format.JSON, valueRepr.asString()))
+ .mapFailure(ex->_Exceptions
+ .illegalArgument(ex, "Unable to parse value %s as String", valueRepr))
+ .ifFailureFail()
+ .getValue().orElse(null);
+ ;
+ if(recoveredValue==null) {
+ return Optional.empty();
+ }
+ val recoveredStringIfAny = _Casts.castTo(String.class, recoveredValue);
+ if(recoveredStringIfAny.isPresent()) {
+ return recoveredStringIfAny;
+ }
+ throw _Exceptions.illegalArgument("Unable to parse value %s as String", recoveredValue.getClass());
+ }
+ throw _Exceptions.illegalArgument("Unable to parse value %s as String"
+ + " (using 'String' as a fallback attempt)", valueRepr);
}
+
@Override
public void appendValueAndFormat(
final ManagedObject valueAdapter,
diff --git a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java
index 9f986c74b4..592aaa0e12 100644
--- a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java
+++ b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java
@@ -38,6 +38,11 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
import org.apache.isis.applib.id.LogicalType;
import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
@@ -51,11 +56,6 @@ import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.isis.viewer.restfulobjects.rendering.service.valuerender.JsonValueEncoderService;
import org.apache.isis.viewer.restfulobjects.rendering.service.valuerender.JsonValueEncoderServiceDefault;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-
import lombok.val;
public class JsonValueEncoderTest_asAdapter {
@@ -132,7 +132,7 @@ public class JsonValueEncoderTest_asAdapter {
representation = new JsonRepresentation(BooleanNode.valueOf(value));
context.checking(new Expectations() {
{
- oneOf(specLoader).specForType(((Object)value).getClass());
+ allowing(specLoader).specForType(((Object)value).getClass());
will(returnValue(Optional.of(mockObjectSpec)));
}
});
@@ -152,7 +152,7 @@ public class JsonValueEncoderTest_asAdapter {
context.checking(new Expectations() {
{
- oneOf(mockValueFacet).fromEncodedString(Format.JSON, "aString");
+ allowing(mockValueFacet).fromEncodedString(Format.JSON, "aString");
will(throwException(new TextEntryParseException("'aString' cannot be parsed as a boolean value")));
}
});
@@ -179,7 +179,7 @@ public class JsonValueEncoderTest_asAdapter {
representation = new JsonRepresentation(IntNode.valueOf(value));
context.checking(new Expectations() {
{
- oneOf(specLoader).specForType(((Object)value).getClass());
+ allowing(specLoader).specForType(((Object)value).getClass());
will(returnValue(Optional.of(mockObjectSpec)));
}
});
@@ -221,7 +221,7 @@ public class JsonValueEncoderTest_asAdapter {
representation = new JsonRepresentation(LongNode.valueOf(value));
context.checking(new Expectations() {
{
- oneOf(specLoader).specForType(((Object)value).getClass());
+ allowing(specLoader).specForType(((Object)value).getClass());
will(returnValue(Optional.of(mockObjectSpec)));
}
});
@@ -241,7 +241,7 @@ public class JsonValueEncoderTest_asAdapter {
context.checking(new Expectations() {
{
- oneOf(mockValueFacet).fromEncodedString(Format.JSON, "aString");
+ allowing(mockValueFacet).fromEncodedString(Format.JSON, "aString");
will(throwException(new TextEntryParseException("'aString' cannot be parsed as a long value")));
}
});
@@ -268,7 +268,7 @@ public class JsonValueEncoderTest_asAdapter {
representation = new JsonRepresentation(DoubleNode.valueOf(value));
context.checking(new Expectations() {
{
- oneOf(specLoader).specForType(((Object)value).getClass());
+ allowing(specLoader).specForType(((Object)value).getClass());
will(returnValue(Optional.of(mockObjectSpec)));
}
});
@@ -301,7 +301,7 @@ public class JsonValueEncoderTest_asAdapter {
representation = new JsonRepresentation(BigIntegerNode.valueOf(value));
context.checking(new Expectations() {
{
- oneOf(specLoader).specForType(value.getClass());
+ allowing(specLoader).specForType(value.getClass());
will(returnValue(Optional.of(mockObjectSpec)));
}
});
@@ -334,7 +334,7 @@ public class JsonValueEncoderTest_asAdapter {
representation = new JsonRepresentation(DecimalNode.valueOf(value));
context.checking(new Expectations() {
{
- oneOf(specLoader).specForType(value.getClass());
+ allowing(specLoader).specForType(value.getClass());
will(returnValue(Optional.of(mockObjectSpec)));
}
@@ -368,7 +368,7 @@ public class JsonValueEncoderTest_asAdapter {
context.checking(new Expectations() {
{
- oneOf(specLoader).specForType(String.class);
+ allowing(specLoader).specForType(String.class);
will(returnValue(Optional.of(mockObjectSpec)));
}
});
@@ -398,6 +398,9 @@ public class JsonValueEncoderTest_asAdapter {
allowing(mockValueFacet).getValueClass();
will(returnValue(valueClass));
+ allowing(mockObjectSpec).isNonScalar();
+ will(returnValue(true));
+
}
});
}