You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2021/06/08 07:51:53 UTC

[isis] 09/19: ISIS-2717: converts ExecutionParametersService into an interface rather than an impl ...

This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch ISIS-2717
in repository https://gitbox.apache.org/repos/asf/isis.git

commit f5887589f8bf5882eb5a575e73255a9280973ab9
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Sun Jun 6 17:15:46 2021 +0100

    ISIS-2717: converts ExecutionParametersService into an interface rather than an impl ...
    
    ... with ExecutionParamterServiceAutoConfiguration providing the fallback.
---
 .../pages/services/ExecutionParametersService.adoc |  27 --
 .../applib/fixturescripts/ExecutionParameters.java | 340 +++------------------
 ...meters.java => ExecutionParametersDefault.java} |  11 +-
 .../fixturescripts/ExecutionParametersService.java |  19 +-
 ...ecutionParametersServiceAutoConfiguration.java} |  42 +--
 .../applib/fixturescripts/FixtureScript.java       |  77 ++++-
 .../applib/fixturescripts/FixtureScripts.java      |  25 +-
 .../src/main/resources/META-INF/spring.factories   |   3 +-
 ...ContextTest.java => ExecutionContext_Test.java} |   8 +-
 ...utionParametersDefault_AsKeyValueMap_Test.java} |  14 +-
 ...t.java => ExecutionParametersDefault_Test.java} |   6 +-
 11 files changed, 184 insertions(+), 388 deletions(-)

diff --git a/testing/fixtures/adoc/modules/fixtures/pages/services/ExecutionParametersService.adoc b/testing/fixtures/adoc/modules/fixtures/pages/services/ExecutionParametersService.adoc
deleted file mode 100644
index afcb411..0000000
--- a/testing/fixtures/adoc/modules/fixtures/pages/services/ExecutionParametersService.adoc
+++ /dev/null
@@ -1,27 +0,0 @@
-= `ExecutionParametersService`
-
-:Notice: 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 ag [...]
-:page-partial:
-
-CAUTION: TODO: this needs to be converted into a hook for refguide-index
-
-
-The `ExecutionParametersService` is used by the framework simply to instantiate the `ExecutionParameters` object.
-The `ExecutionParameters` object in turn is responsible for parsing the string parameter passed when executing fixtures through the UI to the xref:testing:fixtures:services/FixtureScripts.adoc[FixtureScripts] domain service.
-
-== API & Implementation
-
-The API and implementation of this service is simply:
-
-[source,java]
-----
-public class ExecutionParametersService {
-    public ExecutionParameters newExecutionParameters(final String parameters) {
-        return new ExecutionParameters(parameters);
-    }
-}
-----
-
-
-
-
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParameters.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParameters.java
index 1f51483..c133c9c 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParameters.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParameters.java
@@ -35,296 +35,56 @@ import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Maps;
 
 /**
- * @since 1.x {@index}
+ * Represents the execution parameters (as passed initially as a string)
+ * when invoking {@link FixtureScripts#runScript(String, String)}) for
+ * use by the fixtures themselves (accessible using
+ * {@link org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScript.ExecutionContext}).
+ *
+ * @since 2.0 {@index}
  */
-public class ExecutionParameters {
-
-    private static final Pattern keyEqualsValuePattern = Pattern.compile("([^=]*)=(.*)");
-
-    private final String parameters;
-    private final Map<String, String> parameterMap;
-
-    public ExecutionParameters(final String parameters) {
-        this.parameters = parameters;
-        this.parameterMap = asKeyValueMap(parameters);
-    }
-
-    static Map<String, String> asKeyValueMap(final String parameters) {
-        final Map<String, String> keyValues = _Maps.newLinkedHashMap();
-        if (parameters != null) {
-            try {
-                _Strings.splitThenStream(parameters, "\n")
-                .forEach(line->{
-                    final Matcher matcher = keyEqualsValuePattern.matcher(line);
-                    if (matcher.matches()) {
-                        keyValues.put(matcher.group(1).trim(), matcher.group(2).trim());
-                    }
-                });
-            } catch (final Exception e) {
-                // ignore, shouldn't happen
-            }
-        }
-        return keyValues;
-    }
-
-    public String getParameters() {
-        return parameters;
-    }
-
-    public String getParameter(final String parameterName) {
-        return parameterMap.get(parameterName);
-    }
-
-    public <T> T getParameterAsT(final String parameterName, final Class<T> cls) {
-        return _Casts.uncheckedCast(getParameterAsObject(parameterName, cls));
-    }
-
-    protected Object getParameterAsObject(final String parameterName, final Class<?> cls) {
-        final Object value;
-        if (Enum.class.isAssignableFrom(cls)) {
-            Class<?> enumClass = cls;
-            value = getParameterAsEnum(parameterName, _Casts.uncheckedCast(enumClass));
-        } else if (cls == Boolean.class) {
-            value = getParameterAsBoolean(parameterName);
-        } else if (cls == Byte.class) {
-            value = getParameterAsByte(parameterName);
-        } else if (cls == Short.class) {
-            value = getParameterAsShort(parameterName);
-        } else if (cls == Integer.class) {
-            value = getParameterAsInteger(parameterName);
-        } else if (cls == Long.class) {
-            value = getParameterAsLong(parameterName);
-        } else if (cls == Float.class) {
-            value = getParameterAsFloat(parameterName);
-        } else if (cls == Double.class) {
-            value = getParameterAsDouble(parameterName);
-        } else if (cls == Character.class) {
-            value = getParameterAsCharacter(parameterName);
-        } else if (cls == BigDecimal.class) {
-            value = getParameterAsBigDecimal(parameterName);
-        } else if (cls == BigInteger.class) {
-            value = getParameterAsBigInteger(parameterName);
-        } else if (cls == LocalDate.class) {
-            value = getParameterAsLocalDate(parameterName);
-        } else if (cls == LocalDateTime.class) {
-            value = getParameterAsLocalDateTime(parameterName);
-        } else if (cls == String.class) {
-            value = getParameter(parameterName);
-        } else {
-            value = null;
-        }
-        return value;
-    }
-
-    public Boolean getParameterAsBoolean(final String parameterName) {
-        final String value = getParameter(parameterName);
-        if (_Strings.isNullOrEmpty(value)) {
-            return null;
-        }
-        return Boolean.valueOf(value);
-    }
-
-    public Byte getParameterAsByte(final String parameterName) {
-        final String value = getParameter(parameterName);
-        if (_Strings.isNullOrEmpty(value)) {
-            return null;
-        }
-        return Byte.valueOf(value);
-    }
-
-    public Short getParameterAsShort(final String parameterName) {
-        final String value = getParameter(parameterName);
-        if (_Strings.isNullOrEmpty(value)) {
-            return null;
-        }
-        return Short.valueOf(value);
-    }
-
-    public Integer getParameterAsInteger(final String parameterName) {
-        final String value = getParameter(parameterName);
-        if (_Strings.isNullOrEmpty(value)) {
-            return null;
-        }
-        return Integer.valueOf(value);
-    }
-
-    public Long getParameterAsLong(final String parameterName) {
-        final String value = getParameter(parameterName);
-        if (_Strings.isNullOrEmpty(value)) {
-            return null;
-        }
-        return Long.valueOf(value);
-    }
-
-    public Float getParameterAsFloat(final String parameterName) {
-        final String value = getParameter(parameterName);
-        if (_Strings.isNullOrEmpty(value)) {
-            return null;
-        }
-        return Float.valueOf(value);
-    }
-
-    public Double getParameterAsDouble(final String parameterName) {
-        final String value = getParameter(parameterName);
-        if (_Strings.isNullOrEmpty(value)) {
-            return null;
-        }
-        return Double.valueOf(value);
-    }
-
-    public Character getParameterAsCharacter(final String parameterName) {
-        final String value = getParameter(parameterName);
-        if (_Strings.isNullOrEmpty(value)) {
-            return null;
-        }
-        return Character.valueOf(value.charAt(0));
-    }
-
-    public BigInteger getParameterAsBigInteger(final String parameterName) {
-        final String value = getParameter(parameterName);
-        if (_Strings.isNullOrEmpty(value)) {
-            return null;
-        }
-        return new BigInteger(value);
-    }
-
-    public BigDecimal getParameterAsBigDecimal(final String parameterName) {
-        final String value = getParameter(parameterName);
-        if (_Strings.isNullOrEmpty(value)) {
-            return null;
-        }
-        return new BigDecimal(value);
-    }
-
-    public LocalDate getParameterAsLocalDate(final String parameterName) {
-        final String value = getParameter(parameterName);
-        if (value == null) {
-            return null;
-        }
-        return LocalDate.parse(value);
-    }
-
-    public LocalDateTime getParameterAsLocalDateTime(final String parameterName) {
-        final String value = getParameter(parameterName);
-        if (value == null) {
-            return null;
-        }
-        return LocalDateTime.parse(value);
-    }
-
-    public <T extends Enum<T>> T getParameterAsEnum(final String parameterName, final Class<T> enumClass) {
-        final String value = getParameter(parameterName);
-        return valueOfElseNull(enumClass, value);
-    }
-
-    private static <T extends Enum<T>> T valueOfElseNull(final Class<T> enumClass, final String value) {
-        if (value == null) {
-            return null;
-        }
-        final T[] enumConstants = enumClass.getEnumConstants();
-        for (T enumConstant : enumConstants) {
-            if (enumConstant.name().equals(value)) {
-                return enumConstant;
-            }
-        }
-        return null;
-    }
-
-
-    public Map<String, String> getParameterMap() {
-        return Collections.unmodifiableMap(parameterMap);
-    }
-
-    public void setParameterIfNotPresent(final String parameterName, final String parameterValue) {
-        if (parameterName == null) {
-            throw new IllegalArgumentException("parameterName required");
-        }
-        if (parameterValue == null) {
-            // ignore
-            return;
-        }
-        if (parameterMap.containsKey(parameterName)) {
-            // ignore; the existing parameter take precedence
-            return;
-        }
-        parameterMap.put(parameterName, parameterValue);
-    }
-
-    public void setParameter(final String parameterName, final Boolean parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final Byte parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final Short parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final Integer parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final Long parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final Float parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final Double parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final Character parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final BigInteger parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final java.util.Date parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final java.sql.Date parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final LocalDate parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final LocalDateTime parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final DateTime parameterValue) {
-        final StringBuffer buf = new StringBuffer();
-        ISODateTimeFormat.dateTimeParser().printTo(buf, parameterValue);
-        setParameter(parameterName, parameterValue != null ? buf.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final BigDecimal parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.toString() : null);
-    }
-
-    public void setParameter(final String parameterName, final Enum<?> parameterValue) {
-        setParameter(parameterName, parameterValue != null ? parameterValue.name() : null);
-    }
-
-    public void setParameter(final String parameterName, final String parameterValue) {
-        if (parameterName == null) {
-            throw new IllegalArgumentException("parameterName required");
-        }
-        if (parameterValue == null) {
-            // ignore
-            return;
-        }
-        parameterMap.put(parameterName, parameterValue);
-    }
+public interface ExecutionParameters {
+
+    String getParameters();
+
+    Map<String, String> getParameterMap();
+
+    String getParameter(String parameterName);
+
+    <T> T getParameterAsT(String parameterName, Class<T> cls);
+
+    Boolean getParameterAsBoolean(String parameterName);
+    Byte getParameterAsByte(String parameterName);
+    Short getParameterAsShort(String parameterName);
+    Integer getParameterAsInteger(String parameterName);
+    Long getParameterAsLong(String parameterName);
+    Float getParameterAsFloat(String parameterName);
+    Double getParameterAsDouble(String parameterName);
+    Character getParameterAsCharacter(String parameterName);
+    BigInteger getParameterAsBigInteger(String parameterName);
+    BigDecimal getParameterAsBigDecimal(String parameterName);
+    LocalDate getParameterAsLocalDate(String parameterName);
+    LocalDateTime getParameterAsLocalDateTime(String parameterName);
+
+    <T extends Enum<T>> T getParameterAsEnum(String parameterName, Class<T> enumClass);
+
+    void setParameterIfNotPresent(String parameterName, String parameterValue);
+
+    void setParameter(String parameterName, Boolean parameterValue);
+    void setParameter(String parameterName, Byte parameterValue);
+    void setParameter(String parameterName, Short parameterValue);
+    void setParameter(String parameterName, Integer parameterValue);
+    void setParameter(String parameterName, Long parameterValue);
+    void setParameter(String parameterName, Float parameterValue);
+    void setParameter(String parameterName, Double parameterValue);
+    void setParameter(String parameterName, Character parameterValue);
+    void setParameter(String parameterName, BigInteger parameterValue);
+    void setParameter(String parameterName, BigDecimal parameterValue);
+    void setParameter(String parameterName, LocalDate parameterValue);
+    void setParameter(String parameterName, LocalDateTime parameterValue);
+    void setParameter(String parameterName, DateTime parameterValue);
+    void setParameter(String parameterName, java.util.Date parameterValue);
+    void setParameter(String parameterName, java.sql.Date parameterValue);
+    void setParameter(String parameterName, Enum<?> parameterValue);
+    void setParameter(String parameterName, String parameterValue);
 
 }
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParameters.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersDefault.java
similarity index 97%
copy from testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParameters.java
copy to testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersDefault.java
index 1f51483..449ee80 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParameters.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersDefault.java
@@ -35,16 +35,23 @@ import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Maps;
 
 /**
+ * Responsible for parsing the string parameter passed when executing
+ * fixtures through the UI to the {@link FixtureScripts} domain service.
+ *
+ * <p>
+ *     The class is instantiated by the {@link ExecutionParametersService}.
+ * </p>
+ *
  * @since 1.x {@index}
  */
-public class ExecutionParameters {
+public class ExecutionParametersDefault implements ExecutionParameters {
 
     private static final Pattern keyEqualsValuePattern = Pattern.compile("([^=]*)=(.*)");
 
     private final String parameters;
     private final Map<String, String> parameterMap;
 
-    public ExecutionParameters(final String parameters) {
+    public ExecutionParametersDefault(final String parameters) {
         this.parameters = parameters;
         this.parameterMap = asKeyValueMap(parameters);
     }
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersService.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersService.java
index 266a06c..f0af030 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersService.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersService.java
@@ -30,25 +30,18 @@ import org.apache.isis.applib.annotation.OrderPrecedence;
 
 /**
  * Acts as a factory by the {@link FixtureScripts} when
- * instantiating the {@link FixtureScript.ExecutionContext}.
+ * instantiating the {@link FixtureScript.ExecutionContext}, to return an
+ * object able to parse any parameters provided through the UI parameter.
  *
  * <p>
- * Factoring this out as a service potentially allows for extensions to parsing; and also acts as an
- * insurance policy to allow this part of the testing framework to be patched if the chosen parsing algorithms
- * need refinement in the future).
+ * Factoring this out as a service potentially allows for extensions to parsing.
  * </p>
  *
  * @since 1.x {@index}
  */
-@Service
-@Named("isis.test.FixtureExecutionParametersService")
-@Order(OrderPrecedence.MIDPOINT)
-@Primary
-@Qualifier("Default")
-public class ExecutionParametersService {
+@FunctionalInterface
+public interface ExecutionParametersService {
 
-    public ExecutionParameters newExecutionParameters(final String parameters) {
-        return new ExecutionParameters(parameters);
-    }
+    ExecutionParameters newExecutionParameters(final String parameters);
 
 }
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersService.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersServiceAutoConfiguration.java
similarity index 52%
copy from testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersService.java
copy to testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersServiceAutoConfiguration.java
index 266a06c..ce8f3e9 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersService.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersServiceAutoConfiguration.java
@@ -21,6 +21,8 @@ package org.apache.isis.testing.fixtures.applib.fixturescripts;
 import javax.inject.Named;
 
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Primary;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
@@ -29,26 +31,30 @@ import org.apache.isis.applib.annotation.OrderPrecedence;
 
 
 /**
- * Acts as a factory by the {@link FixtureScripts} when
- * instantiating the {@link FixtureScript.ExecutionContext}.
+ * Provides a fallback implementation of {@link ExecutionParametersService} if
+ * none has been provided explicitly by the application itself.
  *
- * <p>
- * Factoring this out as a service potentially allows for extensions to parsing; and also acts as an
- * insurance policy to allow this part of the testing framework to be patched if the chosen parsing algorithms
- * need refinement in the future).
- * </p>
- *
- * @since 1.x {@index}
+ * @since 2.0 {@index}
  */
-@Service
-@Named("isis.test.FixtureExecutionParametersService")
-@Order(OrderPrecedence.MIDPOINT)
-@Primary
-@Qualifier("Default")
-public class ExecutionParametersService {
-
-    public ExecutionParameters newExecutionParameters(final String parameters) {
-        return new ExecutionParameters(parameters);
+public class ExecutionParametersServiceAutoConfiguration {
+
+
+    /**
+     * Returns an implementation of {@link ExecutionParametersService} that
+     * simply instantiates {@link ExecutionParameters} with the provided
+     * parameters (so that the latter parses the parameters and presents them
+     * to {@link FixtureScripts} for inclusion within {@link org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScript.ExecutionContext}.
+     *
+     * @return
+     */
+    @Bean
+    @Named("isis.testing.fixtures.ExecutionParametersServiceDefault")
+    @Order(OrderPrecedence.LATE)
+    @Primary
+    @Qualifier("Default")
+    @ConditionalOnMissingBean(ExecutionParametersService.class)
+    public ExecutionParametersService executionParametersService() {
+        return ExecutionParametersDefault::new;
     }
 
 }
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScript.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScript.java
index 90db06a..fa61fc0 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScript.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScript.java
@@ -49,7 +49,6 @@ import org.apache.isis.commons.internal.base._Strings;
 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.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.testing.fixtures.applib.api.FixtureScriptWithExecutionStrategy;
 import org.apache.isis.testing.fixtures.applib.api.PersonaWithBuilderScript;
 import org.apache.isis.testing.fixtures.applib.api.WithPrereqs;
@@ -59,6 +58,9 @@ import lombok.Setter;
 import lombok.extern.log4j.Log4j2;
 
 /**
+ * Responsible for setting up the system (or more likely a part of the system)
+ * for the purpose of prototyping/demos or for integraton testing.
+ *
  * @since 1.x {@index}
  */
 @Log4j2
@@ -104,8 +106,6 @@ public abstract class FixtureScript {
 
 
 
-    // -- qualifiedName
-
     public String getQualifiedName() {
         return getParentPath() + getLocalName();
     }
@@ -135,14 +135,32 @@ public abstract class FixtureScript {
 
 
 
-
-
     // -- ExecutionContext
 
     /**
+     * Provides an execution context to each {@link FixtureScript} execution,
+     * the primary use case being to allow the fixture script to execute
+     * child fixture scripts (to set up smaller parts of the system).
+     *
+     * <p>
+     *     The execution context also orovides access to parameters that can
+     *     influence how a fixture script executes (for example, specifying how
+     *     many demo objects to set up) and also holds the results of the
+     *     fixture scripts.   Fixture scripts are expected to know how the
+     *     parameter name/key.
+     * </p>
+     *
+     * <p>
+     *     The execution context is also a mechanism by which the results of
+     *     the fixture script (and any children fixture scripts it may have
+     *     executed) can be collected together.  These are rendered to the UI
+     *     by the {@link FixtureScripts} domain service, primarily as a
+     *     convenience for prototyping/demoing.
+     * </p>
+     *
      * @since 1.x {@index}
      */
-    public static class ExecutionContext {
+    public static class ExecutionContext implements ExecutionParameters {
 
         /**
          * Null implementation, to assist with unit testing of {@link FixtureScript}s.
@@ -169,190 +187,229 @@ public abstract class FixtureScript {
         private final FixtureResultList fixtureResultList;
 
         public ExecutionContext(final String parameters, final FixtureScripts fixtureScripts) {
-            this(new ExecutionParameters(parameters), fixtureScripts);
+            this(new ExecutionParametersDefault(parameters), fixtureScripts);
         }
 
         @Programmatic
-        public static ExecutionContext create(final ExecutionParameters executionParameters, final FixtureScripts fixtureScripts) {
+        public static ExecutionContext create(
+                final ExecutionParameters executionParameters,
+                final FixtureScripts fixtureScripts) {
             return new ExecutionContext(executionParameters, fixtureScripts);
         }
 
-        private ExecutionContext(final ExecutionParameters executionParameters, final FixtureScripts fixtureScripts) {
+        private ExecutionContext(
+                final ExecutionParameters executionParameters,
+                final FixtureScripts fixtureScripts) {
             this.fixtureScripts = fixtureScripts;
-            fixtureResultList = new FixtureResultList(fixtureScripts, this);
             this.executionParameters = executionParameters;
+            this.fixtureResultList = new FixtureResultList(fixtureScripts, this);
         }
 
+        @Override
         @Programmatic
         public String getParameters() {
             return executionParameters.getParameters();
         }
 
+        @Override
         @Programmatic
         public Map<String,String> getParameterMap() {
             return executionParameters.getParameterMap();
         }
 
+        @Override
         @Programmatic
         public String getParameter(final String parameterName) {
             return executionParameters.getParameter(parameterName);
         }
 
+        @Override
         @Programmatic
         public <T> T getParameterAsT(final String parameterName, final Class<T> cls) {
             return executionParameters.getParameterAsT(parameterName,cls);
         }
 
+        @Override
         @Programmatic
         public Boolean getParameterAsBoolean(final String parameterName) {
             return executionParameters.getParameterAsBoolean(parameterName);
         }
 
+        @Override
         @Programmatic
         public Byte getParameterAsByte(final String parameterName) {
             return executionParameters.getParameterAsByte(parameterName);
         }
 
+        @Override
         @Programmatic
         public Short getParameterAsShort(final String parameterName) {
             return executionParameters.getParameterAsShort(parameterName);
         }
 
+        @Override
         @Programmatic
         public Integer getParameterAsInteger(final String parameterName) {
             return executionParameters.getParameterAsInteger(parameterName);
         }
 
+        @Override
         @Programmatic
         public Long getParameterAsLong(final String parameterName) {
             return executionParameters.getParameterAsLong(parameterName);
         }
 
+        @Override
         @Programmatic
         public Float getParameterAsFloat(final String parameterName) {
             return executionParameters.getParameterAsFloat(parameterName);
         }
 
+        @Override
         @Programmatic
         public Double getParameterAsDouble(final String parameterName) {
             return executionParameters.getParameterAsDouble(parameterName);
         }
 
+        @Override
         @Programmatic
         public Character getParameterAsCharacter(final String parameterName) {
             return executionParameters.getParameterAsCharacter(parameterName);
         }
 
+        @Override
         @Programmatic
         public BigInteger getParameterAsBigInteger(final String parameterName) {
             return executionParameters.getParameterAsBigInteger(parameterName);
         }
 
+        @Override
         @Programmatic
         public BigDecimal getParameterAsBigDecimal(final String parameterName) {
             return executionParameters.getParameterAsBigDecimal(parameterName);
         }
 
+        @Override
         @Programmatic
         public LocalDate getParameterAsLocalDate(final String parameterName) {
             return executionParameters.getParameterAsLocalDate(parameterName);
         }
 
+        @Override
         @Programmatic
         public LocalDateTime getParameterAsLocalDateTime(final String parameterName) {
             return executionParameters.getParameterAsLocalDateTime(parameterName);
         }
 
+        @Override
         @Programmatic
         public <T extends Enum<T>> T getParameterAsEnum(final String parameterName, final Class<T> enumClass) {
             return executionParameters.getParameterAsEnum(parameterName, enumClass);
         }
 
+        @Override
         @Programmatic
         public void setParameterIfNotPresent(final String parameterName, final String parameterValue) {
             executionParameters.setParameterIfNotPresent(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final Boolean parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final Byte parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final Short parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final Integer parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final Long parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final Float parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final Double parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final Character parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final BigInteger parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final java.util.Date parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final java.sql.Date parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final LocalDate parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final LocalDateTime parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final org.joda.time.DateTime parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final BigDecimal parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final Enum<?> parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
         }
 
+        @Override
         @Programmatic
         public void setParameter(final String parameterName, final String parameterValue) {
             executionParameters.setParameter(parameterName, parameterValue);
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScripts.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScripts.java
index befa3a5..ba159e4 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScripts.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScripts.java
@@ -65,6 +65,9 @@ import lombok.val;
 
 
 /**
+ * Provides the mechanism to execute {@link FixtureScript}s from the UI of
+ * a domain app; and can also be used within integration testing.
+ *
  * @since 1.x {@index}
  */
 @DomainService(
@@ -79,11 +82,8 @@ public class FixtureScripts {
 
     public static final String LOGICAL_TYPE_NAME = IsisModuleTestingFixturesApplib.NAMESPACE + ".FixtureScripts"; // secman seeding
 
-    //  @Inject private FactoryService factoryService;
     @Inject private TitleService titleService;
     @Inject private JaxbService jaxbService;
-    // @Inject private BookmarkService bookmarkService;
-    // @Inject private ServiceRegistry serviceRegistry;
     @Inject private ServiceInjector serviceInjector;
     @Inject private RepositoryService repositoryService;
     @Inject private TransactionService transactionService;
@@ -99,6 +99,8 @@ public class FixtureScripts {
      * How to handle objects that are to be
      * {@link FixtureScripts#newFixtureResult(FixtureScript, String, Object, boolean) added}
      * into a {@link FixtureResult} but which are not yet persisted.
+     *
+     * @since 1.x {@index}
      */
     public enum NonPersistedObjectsStrategy {
         PERSIST,
@@ -113,8 +115,9 @@ public class FixtureScripts {
      *     {@link FixtureScripts} service; there isn't (currently) any way to mix-and-match fixture scripts that are
      *     written with differing semantics in mind.  Ideally it should be the responsibility of the fixture script
      *     itself to determine whether it should be run.  As a partial solution to this, the
-     *
      * </p>
+     *
+     * @since 1.x {@index}
      */
     public enum MultipleExecutionStrategy {
         /**
@@ -204,11 +207,10 @@ public class FixtureScripts {
     private final SortedMap<String,FixtureScript> fixtureScriptByFriendlyName;
 
     public FixtureScripts(
-            final Optional<FixtureScriptsSpecificationProvider> fixtureScriptsSpecificationProvider,
+            final FixtureScriptsSpecificationProvider fixtureScriptsSpecificationProvider,
             final ServiceRegistry serviceRegistry) {
 
-        this.specification = fixtureScriptsSpecificationProvider.orElse(() -> FixtureScriptsSpecification.builder(PACKAGE_PREFIX).build()).getSpecification();
-        // this.serviceRegistry = serviceRegistry;
+        this.specification = fixtureScriptsSpecificationProvider.getSpecification();
 
         val packagePrefix = specification.getPackagePrefix();
         fixtureScriptByFriendlyName =
@@ -216,7 +218,7 @@ public class FixtureScripts {
                 .filter(Objects::nonNull)
                 .filter(fixtureScript -> fixtureScript.getClass().getPackage().getName().startsWith(packagePrefix))
                 .collect(Collectors.toMap(FixtureScript::getFriendlyName, Function.identity(),
-                        (v1,v2) ->{ throw new RuntimeException(String.format("Duplicate key for values %s and %s", v1, v2));},
+                        (v1,v2) ->{ throw new RuntimeException(String.format("Two FixtureScript's have the same friendly name '%s", v1));},
                         TreeMap::new));
     }
 
@@ -434,11 +436,8 @@ public class FixtureScripts {
 
     @Programmatic
     public FixtureScript.ExecutionContext newExecutionContext(final String parameters) {
-        final ExecutionParameters executionParameters =
-                executionParametersService != null
-                ? executionParametersService.newExecutionParameters(parameters)
-                        : new ExecutionParameters(parameters);
-                return FixtureScript.ExecutionContext.create(executionParameters, this);
+        val executionParameters = executionParametersService.newExecutionParameters(parameters);
+        return FixtureScript.ExecutionContext.create(executionParameters, this);
     }
 
 
diff --git a/testing/fixtures/applib/src/main/resources/META-INF/spring.factories b/testing/fixtures/applib/src/main/resources/META-INF/spring.factories
index b67108e..76874b2 100644
--- a/testing/fixtures/applib/src/main/resources/META-INF/spring.factories
+++ b/testing/fixtures/applib/src/main/resources/META-INF/spring.factories
@@ -1,2 +1,3 @@
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-  org.apache.isis.testing.fixtures.applib.fixturespec.FixtureScriptsSpecificationProviderAutoConfiguration
+  org.apache.isis.testing.fixtures.applib.fixturespec.FixtureScriptsSpecificationProviderAutoConfiguration,\
+  org.apache.isis.testing.fixtures.applib.fixturescripts.ExecutionParametersServiceAutoConfiguration
diff --git a/testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionContextTest.java b/testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionContext_Test.java
similarity index 97%
rename from testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionContextTest.java
rename to testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionContext_Test.java
index 1acda60..e9f37c0 100644
--- a/testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionContextTest.java
+++ b/testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionContext_Test.java
@@ -26,9 +26,9 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-public class ExecutionContextTest {
+public class ExecutionContext_Test {
 
-    public static class GetParameter extends ExecutionContextTest {
+    public static class GetParameter extends ExecutionContext_Test {
 
         @Test
         public void happyCase() throws Exception {
@@ -103,7 +103,7 @@ public class ExecutionContextTest {
         }
 
     }
-    public static class SetParameterIfNotPresent extends ExecutionContextTest {
+    public static class SetParameterIfNotPresent extends ExecutionContext_Test {
 
         @Test
         public void whenNotPresent() throws Exception {
@@ -124,4 +124,4 @@ public class ExecutionContextTest {
     }
 
 
-}
\ No newline at end of file
+}
diff --git a/testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParameters_AsKeyValueMap_Test.java b/testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersDefault_AsKeyValueMap_Test.java
similarity index 74%
rename from testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParameters_AsKeyValueMap_Test.java
rename to testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersDefault_AsKeyValueMap_Test.java
index 3fe688c..fd03619 100644
--- a/testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParameters_AsKeyValueMap_Test.java
+++ b/testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersDefault_AsKeyValueMap_Test.java
@@ -26,11 +26,11 @@ import org.junit.jupiter.api.Test;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-public class ExecutionParameters_AsKeyValueMap_Test extends ExecutionContextTest {
+public class ExecutionParametersDefault_AsKeyValueMap_Test extends ExecutionContext_Test {
 
     @Test
     public void happyCase() throws Exception {
-        final Map<String, String> map = ExecutionParameters.asKeyValueMap("foo=bar\nbop=baz");
+        final Map<String, String> map = ExecutionParametersDefault.asKeyValueMap("foo=bar\nbop=baz");
         assertThat(map.size(), is(2));
 
         assertThat(map.get("foo"), is("bar"));
@@ -39,20 +39,20 @@ public class ExecutionParameters_AsKeyValueMap_Test extends ExecutionContextTest
 
     @Test
     public void givenNull() throws Exception {
-        final Map<String, String> map = ExecutionParameters.asKeyValueMap(null);
+        final Map<String, String> map = ExecutionParametersDefault.asKeyValueMap(null);
         assertThat(map.size(), is(0));
     }
 
     @Test
     public void givenEmpty() throws Exception {
-        final Map<String, String> map = ExecutionParameters.asKeyValueMap("");
+        final Map<String, String> map = ExecutionParametersDefault.asKeyValueMap("");
         assertThat(map.size(), is(0));
     }
 
     @Test
     public void trim() throws Exception {
 
-        final Map<String, String> map = ExecutionParameters.asKeyValueMap(" foo=bar\nbop=baz \n bip = bap ");
+        final Map<String, String> map = ExecutionParametersDefault.asKeyValueMap(" foo=bar\nbop=baz \n bip = bap ");
         assertThat(map.size(), is(3));
 
         assertThat(map.get("foo"), is("bar"));
@@ -62,13 +62,13 @@ public class ExecutionParameters_AsKeyValueMap_Test extends ExecutionContextTest
 
     @Test
     public void malformed() throws Exception {
-        final Map<String, String> map = ExecutionParameters.asKeyValueMap("abcde");
+        final Map<String, String> map = ExecutionParametersDefault.asKeyValueMap("abcde");
         assertThat(map.size(), is(0));
     }
 
     @Test
     public void partiallyMalformed() throws Exception {
-        final Map<String, String> map = ExecutionParameters.asKeyValueMap("foo=bar\nabcde\nbop=baz");
+        final Map<String, String> map = ExecutionParametersDefault.asKeyValueMap("foo=bar\nabcde\nbop=baz");
         assertThat(map.size(), is(2));
 
         assertThat(map.get("foo"), is("bar"));
diff --git a/testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParameters_Test.java b/testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersDefault_Test.java
similarity index 98%
rename from testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParameters_Test.java
rename to testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersDefault_Test.java
index 2a9b24d..f6643e6 100644
--- a/testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParameters_Test.java
+++ b/testing/fixtures/applib/src/test/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersDefault_Test.java
@@ -29,13 +29,13 @@ import org.junit.jupiter.api.Test;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-public class ExecutionParameters_Test {
+public class ExecutionParametersDefault_Test {
 
     private ExecutionParameters executionParameters;
 
     @BeforeEach
     public void setUp() throws Exception {
-        executionParameters = new ExecutionParameters("");
+        executionParameters = new ExecutionParametersDefault("");
     }
 
     @Test
@@ -269,4 +269,4 @@ public class ExecutionParameters_Test {
     }
 
 
-}
\ No newline at end of file
+}