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 2021/04/30 09:09:30 UTC
[isis] branch master updated: ISIS-2626: SpecLoader: provide a
side-effect free MM validation version
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 fa7fa10 ISIS-2626: SpecLoader: provide a side-effect free MM validation version
fa7fa10 is described below
commit fa7fa1088ca20f267d5728c21fda3b4e57758d0b
Author: ahuber@apache.org <ah...@luna>
AuthorDate: Fri Apr 30 11:09:11 2021 +0200
ISIS-2626: SpecLoader: provide a side-effect free MM validation version
---
.../org/apache/isis/commons/internal/base/_Lazy.java | 6 ++++++
.../isis/commons/internal/base/_Lazy_Simple.java | 6 ++++++
.../isis/commons/internal/base/_Lazy_ThreadSafe.java | 8 ++++++++
.../commons/internal/base/_Lazy_ThreadSafeAndWeak.java | 6 ++++++
.../core/metamodel/specloader/SpecificationLoader.java | 16 ++++++++++++++--
.../specloader/SpecificationLoaderDefault.java | 14 ++++++++++----
.../ViewModelSemanticCheckingFacetFactoryTest.java | 2 +-
.../session/InteractionFactoryDefault.java | 2 +-
...sionAnnotationFacetFactoryTest_refineMetaModel.java | 2 +-
.../util/interaction/InteractionTestAbstract.java | 2 +-
.../applib/validate/DomainModelValidator.java | 2 +-
.../webmodule/IsisRestfulObjectsInteractionFilter.java | 7 +++++--
.../viewer/integration/WebRequestCycleForIsis.java | 18 +++++++++++++-----
13 files changed, 73 insertions(+), 18 deletions(-)
diff --git a/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy.java b/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy.java
index 63a6ba4..ac967b6 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy.java
@@ -19,6 +19,7 @@
package org.apache.isis.commons.internal.base;
+import java.util.Optional;
import java.util.function.Supplier;
/**
@@ -59,6 +60,11 @@ public interface _Lazy<T> extends Supplier<T> {
public T get();
/**
+ * Optionally returns the value, based on whether this lazy got initialized and holds a memoized value.
+ */
+ public Optional<T> getMemoized();
+
+ /**
* Sets the memoized value, if not already memoized.
* @param value
* @throws IllegalStateException if already memoized
diff --git a/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy_Simple.java b/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy_Simple.java
index 9b24018..bf951c1 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy_Simple.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy_Simple.java
@@ -19,6 +19,7 @@
package org.apache.isis.commons.internal.base;
+import java.util.Optional;
import java.util.function.Supplier;
import org.apache.isis.commons.internal.exceptions._Exceptions;
@@ -58,6 +59,11 @@ final class _Lazy_Simple<T> implements _Lazy<T> {
memoized = true;
return value = supplier.get();
}
+
+ @Override
+ public Optional<T> getMemoized() {
+ return Optional.ofNullable(value);
+ }
@Override
public void set(T value) {
diff --git a/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy_ThreadSafe.java b/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy_ThreadSafe.java
index 0048e61..444bfe3 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy_ThreadSafe.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy_ThreadSafe.java
@@ -19,6 +19,7 @@
package org.apache.isis.commons.internal.base;
+import java.util.Optional;
import java.util.function.Supplier;
import org.apache.isis.commons.internal.exceptions._Exceptions;
@@ -66,6 +67,13 @@ final class _Lazy_ThreadSafe<T> implements _Lazy<T> {
}
@Override
+ public Optional<T> getMemoized() {
+ synchronized (this) {
+ return Optional.ofNullable(value);
+ }
+ }
+
+ @Override
public void set(T value) {
synchronized (this) {
if(memoized) {
diff --git a/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy_ThreadSafeAndWeak.java b/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy_ThreadSafeAndWeak.java
index 9052d7b..7014e62 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy_ThreadSafeAndWeak.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy_ThreadSafeAndWeak.java
@@ -20,6 +20,7 @@
package org.apache.isis.commons.internal.base;
import java.lang.ref.WeakReference;
+import java.util.Optional;
import java.util.function.Supplier;
import org.apache.isis.commons.internal.exceptions._Exceptions;
@@ -70,6 +71,11 @@ final class _Lazy_ThreadSafeAndWeak<T> implements _Lazy<T> {
}
@Override
+ public Optional<T> getMemoized() {
+ throw _Exceptions.unsupportedOperation("undecidable for weak references");
+ }
+
+ @Override
public void set(T newValue) {
synchronized (this) {
weakValueReference = new WeakReference<T>(newValue);
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 0f5bcc9..3ceea19 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
@@ -61,12 +61,24 @@ public interface SpecificationLoader {
/**
* Returns the collected results of the various {@link MetaModelValidator}s configured with
- * the {@link ProgrammingModel}.
+ * the {@link ProgrammingModel}. As a side-effect, triggers meta-model validation, if that has
+ * not happened already. Viewers should call the side-effect free
+ * {@link #getValidationResult() variant} instead.
*
* @apiNote Some of the {@link MetaModelValidator}s run during {@link #createMetaModel()},
* others are only triggered when calling this method.
+ * @see #getValidationResult()
*/
- ValidationFailures getValidationResult();
+ ValidationFailures getOrAssessValidationResult();
+
+ /**
+ * Optionally returns the collected results of the various {@link MetaModelValidator}s configured with
+ * the {@link ProgrammingModel}, based on whether the <i>Application<i> is yet fully initialized.
+ *
+ * @apiNote This is the side-effect free variant of {@link #getOrAssessValidationResult()}
+ * @see #getOrAssessValidationResult()
+ */
+ Optional<ValidationFailures> getValidationResult();
void addValidationFailure(ValidationFailure validationFailure);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
index c143e0b..886249f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
@@ -20,6 +20,7 @@ package org.apache.isis.core.metamodel.specloader;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Optional;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -302,7 +303,7 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
}
log.info(" - running remaining validators");
- _Blackhole.consume(getValidationResult()); // as a side effect memoizes the validation result
+ _Blackhole.consume(getOrAssessValidationResult()); // as a side effect memoizes the validation result
stopWatch.stop();
log.info("Metamodel created in " + (long)stopWatch.getMillis() + " ms.");
@@ -313,7 +314,12 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
}
@Override
- public ValidationFailures getValidationResult() {
+ public Optional<ValidationFailures> getValidationResult() {
+ return validationResult.getMemoized();
+ }
+
+ @Override
+ public ValidationFailures getOrAssessValidationResult() {
return validationResult.get();
}
@@ -404,12 +410,12 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
validationResult.clear(); // invalidate
// potentially triggers a call to the method we are currently in,
// which adds more entries to the validationQueue
- getValidationResult();
+ getOrAssessValidationResult();
}
// only after things have settled we offer feedback to the user (interface)
- final ValidationFailures validationFailures = getValidationResult();
+ final ValidationFailures validationFailures = getOrAssessValidationResult();
if(validationFailures.hasFailures()) {
throw _Exceptions.illegalState(String.join("\n", validationFailures.getMessages("[%d] %s")));
}
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java
index 1a9ed7e..69cf9eb 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/ViewModelSemanticCheckingFacetFactoryTest.java
@@ -154,7 +154,7 @@ public class ViewModelSemanticCheckingFacetFactoryTest {
((MetaModelContextAware)holder).setMetaModelContext(metaModelContext);
facetFactory.process(new FacetFactory.ProcessClassContext(cls, null, holder));
- return metaModelContext.getSpecificationLoader().getValidationResult();
+ return metaModelContext.getSpecificationLoader().getOrAssessValidationResult();
}
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionFactoryDefault.java
index ba6b67f..87d78db 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionFactoryDefault.java
@@ -134,7 +134,7 @@ implements
taskList.await();
{ // log any validation failures, experimental code however, not sure how to best propagate failures
- val validationResult = specificationLoader.getValidationResult();
+ val validationResult = specificationLoader.getOrAssessValidationResult();
if(validationResult.getNumberOfFailures()==0) {
log.info("Validation PASSED");
} else {
diff --git a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactoryTest_refineMetaModel.java b/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactoryTest_refineMetaModel.java
index e85bd74..d6ed273 100644
--- a/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactoryTest_refineMetaModel.java
+++ b/persistence/jdo/metamodel/src/test/java/org/apache/isis/persistence/jdo/metamodel/facets/object/version/JdoVersionAnnotationFacetFactoryTest_refineMetaModel.java
@@ -287,7 +287,7 @@ public class JdoVersionAnnotationFacetFactoryTest_refineMetaModel {
private ValidationFailures processThenValidate(ObjectSpecification spec) {
val specLoader = metaModelContext.getSpecificationLoader();
specLoader.specForType(spec.getCorrespondingClass()).get(); // fail if empty
- return specLoader.getValidationResult();
+ return specLoader.getOrAssessValidationResult();
}
}
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/InteractionTestAbstract.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/InteractionTestAbstract.java
index 7647f10..5af73fe 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/InteractionTestAbstract.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/InteractionTestAbstract.java
@@ -108,7 +108,7 @@ public abstract class InteractionTestAbstract extends IsisIntegrationTestAbstrac
protected void assertMetamodelValid() {
val specLoader = objectManager.getMetaModelContext().getSpecificationLoader();
- assertEquals(Collections.<String>emptyList(), specLoader.getValidationResult().getMessages());
+ assertEquals(Collections.<String>emptyList(), specLoader.getOrAssessValidationResult().getMessages());
}
protected void assertComponentWiseEquals(Object a, Object b) {
diff --git a/testing/integtestsupport/applib/src/main/java/org/apache/isis/testing/integtestsupport/applib/validate/DomainModelValidator.java b/testing/integtestsupport/applib/src/main/java/org/apache/isis/testing/integtestsupport/applib/validate/DomainModelValidator.java
index 7da2d20..6555c36 100644
--- a/testing/integtestsupport/applib/src/main/java/org/apache/isis/testing/integtestsupport/applib/validate/DomainModelValidator.java
+++ b/testing/integtestsupport/applib/src/main/java/org/apache/isis/testing/integtestsupport/applib/validate/DomainModelValidator.java
@@ -74,7 +74,7 @@ public class DomainModelValidator {
}
}
- this.validationFailures = specificationLoader.getValidationResult();
+ this.validationFailures = specificationLoader.getOrAssessValidationResult();
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/webmodule/IsisRestfulObjectsInteractionFilter.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/webmodule/IsisRestfulObjectsInteractionFilter.java
index bbb8372..72e4ec2 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/webmodule/IsisRestfulObjectsInteractionFilter.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/webmodule/IsisRestfulObjectsInteractionFilter.java
@@ -46,6 +46,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.apache.isis.applib.services.xactn.TransactionService;
import org.apache.isis.commons.internal.base._Strings;
import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.commons.internal.factory._InstanceUtil;
import org.apache.isis.core.interaction.session.InteractionFactory;
import org.apache.isis.core.metamodel.commons.StringExtensions;
@@ -412,10 +413,12 @@ public class IsisRestfulObjectsInteractionFilter implements Filter {
private static void ensureMetamodelIsValid(SpecificationLoader specificationLoader) {
- val validationResult = specificationLoader.getValidationResult();
+ // using side-effect free access to MM validation result
+ val validationResult = specificationLoader.getValidationResult()
+ .orElseThrow(()->_Exceptions.illegalState("Application is not fully initilized yet."));
if(validationResult.hasFailures()) {
throw new MetaModelInvalidException(validationResult.getAsLineNumberedString());
- }
+ }
}
diff --git a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/WebRequestCycleForIsis.java b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/WebRequestCycleForIsis.java
index 41fe163..c488d62 100644
--- a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/WebRequestCycleForIsis.java
+++ b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/WebRequestCycleForIsis.java
@@ -172,7 +172,9 @@ public class WebRequestCycleForIsis implements IRequestCycleListener {
} else if(handler instanceof RenderPageRequestHandler) {
- val validationResult = getCommonContext().getSpecificationLoader().getValidationResult();
+ // using side-effect free access to MM validation result
+ val validationResult = getCommonContext().getSpecificationLoader().getValidationResult()
+ .orElseThrow(()->_Exceptions.illegalState("Application is not fully initilized yet."));
if(validationResult.hasFailures()) {
RenderPageRequestHandler requestHandler = (RenderPageRequestHandler) handler;
@@ -272,8 +274,11 @@ public class WebRequestCycleForIsis implements IRequestCycleListener {
log.debug("onException {}", ex.getClass().getSimpleName());
- val validationResult = getCommonContext().getSpecificationLoader().getValidationResult();
- if(validationResult.hasFailures()) {
+ // using side-effect free access to MM validation result
+ val validationResult = getCommonContext().getSpecificationLoader().getValidationResult()
+ .orElse(null);
+ if(validationResult!=null
+ && validationResult.hasFailures()) {
val mmvErrorPage = new MmvErrorPage(validationResult.getMessages("[%d] %s"));
return new RenderPageRequestHandler(new PageProvider(mmvErrorPage), RedirectPolicy.ALWAYS_REDIRECT);
}
@@ -385,8 +390,11 @@ public class WebRequestCycleForIsis implements IRequestCycleListener {
return null;
}
- val validationResult = commmonContext.getSpecificationLoader().getValidationResult();
- if(validationResult.hasFailures()) {
+ // using side-effect free access to MM validation result
+ val validationResult = getCommonContext().getSpecificationLoader().getValidationResult()
+ .orElse(null);
+ if(validationResult!=null
+ && validationResult.hasFailures()) {
return new MmvErrorPage(validationResult.getMessages("[%d] %s"));
}