/*
* 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.applib.fixturescripts;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.apache.isis.applib.AbstractViewModel;
import org.apache.isis.applib.DomainObjectContainer;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.annotation.PropertyLayout;
import org.apache.isis.applib.annotation.Title;
import org.apache.isis.applib.annotation.ViewModelLayout;
import org.apache.isis.applib.annotation.Where;
import org.apache.isis.applib.fixtures.FixtureType;
import org.apache.isis.applib.fixtures.InstallableFixture;
import org.apache.isis.applib.services.wrapper.WrapperFactory;
import org.apache.isis.applib.services.xactn.TransactionService;
@ViewModelLayout(named="Script")
public abstract class FixtureScript
extends AbstractViewModel
implements InstallableFixture {
protected static final String PATH_SEPARATOR = "/";
//region > constructors
/**
* Initializes a {@link Discoverability#NON_DISCOVERABLE} fixture, with
* {@link #getFriendlyName()} and {@link #getLocalName()} derived from the class name.
*
* <p>
* Use {@link #withDiscoverability(Discoverability)} to override.
*/
public FixtureScript() {
this(null, null);
}
/**
* Initializes a {@link Discoverability#NON_DISCOVERABLE} fixture.
*
* <p>
* Use {@link #withDiscoverability(Discoverability)} to override.
*
* @param friendlyName - if null, will be derived from class name
* @param localName - if null, will be derived from class name
*/
public FixtureScript(final String friendlyName, final String localName) {
this(friendlyName, localName, Discoverability.NON_DISCOVERABLE);
}
/**
* @param friendlyName - if null, will be derived from class name
* @param localName - if null, will be derived from class name
* @param discoverability - whether this fixture script can be rendered as a choice to execute through {@link org.apache.isis.applib.fixturescripts.FixtureScripts#runFixtureScript(FixtureScript, String)}}.
*/
public FixtureScript(
final String friendlyName,
final String localName,
final Discoverability discoverability) {
this.localName = localNameElseDerived(localName);
this.friendlyName = friendlyNameElseDerived(friendlyName);
this.parentPath = "";
this.discoverability = discoverability;
// enable tracing by default, to stdout
withTracing();
}
protected String localNameElseDerived(final String str) {
return str != null ? str : StringUtil.asLowerDashed(friendlyNameElseDerived(str));
}
protected String friendlyNameElseDerived(final String str) {
return str != null ? str : StringUtil.asNaturalName2(getClass().getSimpleName());
}
//endregion
//region > tracing
private PrintStream tracePrintStream;
/**
* Enable tracing of the execution to the provided {@link java.io.PrintStream}.
*/
@Programmatic
public FixtureScript withTracing(final PrintStream tracePrintStream) {
this.tracePrintStream = tracePrintStream;
return this;
}
/**
* Enable tracing of the execution to stdout.
*/
@Programmatic
public FixtureScript withTracing() {
return withTracing(System.out);
}
//endregion
//region > viewModel impl
@Programmatic
@Override
public String viewModelMemento() {
return fixtureScripts.mementoFor(this);
}
@Programmatic
@Override
public void viewModelInit(final String mementoStr) {
fixtureScripts.initOf(mementoStr, this);
}
//endregion
//region > qualifiedName
@Programmatic
public String getQualifiedName() {
return getParentPath() + getLocalName();
}
//endregion
//region > friendlyName (property)
private String friendlyName;
@Title
@PropertyLayout(hidden = Where.EVERYWHERE)
public String getFriendlyName() {
return friendlyName;
}
public void setFriendlyName(final String friendlyName) {
this.friendlyName = friendlyName;
}
//endregion
//region > localName
private String localName;
/**
* Will always be populated, initially by the default name, but can be
* {@link #setLocalName(String) overridden}.
*/
@Programmatic
public String getLocalName() {
return localName;
}
public void setLocalName(final String localName) {
this.localName = localName;
}
//endregion
//region > parentPath
private String parentPath;
/**
* Path of the parent of this script (if any), with trailing {@value #PATH_SEPARATOR}.
*/
@Programmatic
public String getParentPath() {
return parentPath;
}
@Programmatic
public void setParentPath(final String parentPath) {
this.parentPath = parentPath;
}
//endregion
//region > discoverability
/**
* Whether this fixture script should be automatically discoverable or not.
*/
public enum Discoverability {
/**
* the fixture script is discoverable and so will be listed by the
* {@link FixtureScripts#runFixtureScript(FixtureScript,String) run fixture script} action
*/
DISCOVERABLE,
/**
* The fixture script is non-discoverable and so will <i>not</i> be listed by the
* {@link FixtureScripts#runFixtureScript(FixtureScript,String) run fixture script} action
*/
NON_DISCOVERABLE
}
private Discoverability discoverability;
/**
* Whether this fixture script is {@link Discoverability discoverable} (in other words
* whether it will be listed to be run in the {@link FixtureScripts#runFixtureScript(FixtureScript, String) run fixture script} action.
*
* <p>
* By default {@link DiscoverableFixtureScript}s are {@link Discoverability#DISCOVERABLE discoverable}, all other
* {@link FixtureScript}s are {@link Discoverability#NON_DISCOVERABLE not}. This can be overridden in the
* constructor, however or by calling the {@link #withDiscoverability(org.apache.isis.applib.fixturescripts.FixtureScript.Discoverability) setter}.
*/
@Programmatic
public boolean isDiscoverable() {
return discoverability == Discoverability.DISCOVERABLE;
}
@Programmatic
public FixtureScript withDiscoverability(final Discoverability discoverability) {
this.discoverability = discoverability;
return this;
}
//endregion
//region > ExecutionContext
public static class ExecutionContext {
/**
* Null implementation, to assist with unit testing of {@link org.apache.isis.applib.fixturescripts.FixtureScript}s.
*/
public static final ExecutionContext NOOP = new ExecutionContext((String)null, null) {
@Override
public <T> T add(final FixtureScript script, final T object) {
return object;
}
@Override
public <T> T addResult(final FixtureScript script, final T object) {
return object;
}
@Override
public <T> T add(final FixtureScript script, final String key, final T object) {
return object;
}
@Override
public <T> T addResult(final FixtureScript script, final String key, final T object) {
return object;
}
@Override
public List<FixtureResult> getResults() {
return Collections.emptyList();
}
};
private final ExecutionParameters executionParameters;
private final FixtureScripts fixtureScripts;
private final FixtureResultList fixtureResultList;
public ExecutionContext(final String parameters, final FixtureScripts fixtureScripts) {
this(new ExecutionParameters(parameters), fixtureScripts);
}
@Programmatic
public static ExecutionContext create(final ExecutionParameters executionParameters, final FixtureScripts fixtureScripts) {
return new ExecutionContext(executionParameters, fixtureScripts);
}
private ExecutionContext(final ExecutionParameters executionParameters, final FixtureScripts fixtureScripts) {
this.fixtureScripts = fixtureScripts;
fixtureResultList = new FixtureResultList(fixtureScripts, this);
this.executionParameters = executionParameters;
}
/**
* @deprecated - this shouldn't have public visibility.
*/
@Deprecated
public static Map<String, String> asKeyValueMap(final String parameters) {
return ExecutionParameters.asKeyValueMap(parameters);
}
@Programmatic
public String getParameters() {
return executionParameters.getParameters();
}
@Programmatic
public Map<String,String> getParameterMap() {
return executionParameters.getParameterMap();
}
@Programmatic
public String getParameter(final String parameterName) {
return executionParameters.getParameter(parameterName);
}
@Programmatic
public <T> T getParameterAsT(final String parameterName, final Class<T> cls) {
return executionParameters.getParameterAsT(parameterName,cls);
}
@Programmatic
public Boolean getParameterAsBoolean(final String parameterName) {
return executionParameters.getParameterAsBoolean(parameterName);
}
@Programmatic
public Byte getParameterAsByte(final String parameterName) {
return executionParameters.getParameterAsByte(parameterName);
}
@Programmatic
public Short getParameterAsShort(final String parameterName) {
return executionParameters.getParameterAsShort(parameterName);
}
@Programmatic
public Integer getParameterAsInteger(final String parameterName) {
return executionParameters.getParameterAsInteger(parameterName);
}
@Programmatic
public Long getParameterAsLong(final String parameterName) {
return executionParameters.getParameterAsLong(parameterName);
}
@Programmatic
public Float getParameterAsFloat(final String parameterName) {
return executionParameters.getParameterAsFloat(parameterName);
}
@Programmatic
public Double getParameterAsDouble(final String parameterName) {
return executionParameters.getParameterAsDouble(parameterName);
}
@Programmatic
public Character getParameterAsCharacter(final String parameterName) {
return executionParameters.getParameterAsCharacter(parameterName);
}
@Programmatic
public BigInteger getParameterAsBigInteger(final String parameterName) {
return executionParameters.getParameterAsBigInteger(parameterName);
}
@Programmatic
public BigDecimal getParameterAsBigDecimal(final String parameterName) {
return executionParameters.getParameterAsBigDecimal(parameterName);
}
@Programmatic
public LocalDate getParameterAsLocalDate(final String parameterName) {
return executionParameters.getParameterAsLocalDate(parameterName);
}
@Programmatic
public LocalDateTime getParameterAsLocalDateTime(final String parameterName) {
return executionParameters.getParameterAsLocalDateTime(parameterName);
}
@Programmatic
public <T extends Enum<T>> T getParameterAsEnum(final String parameterName, final Class<T> enumClass) {
return executionParameters.getParameterAsEnum(parameterName, enumClass);
}
@Programmatic
public void setParameterIfNotPresent(final String parameterName, final String parameterValue) {
executionParameters.setParameterIfNotPresent(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final Boolean parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final Byte parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final Short parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final Integer parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final Long parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final Float parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final Double parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final Character parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final BigInteger parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final java.util.Date parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final java.sql.Date parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final LocalDate parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final LocalDateTime parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final org.joda.time.DateTime parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final BigDecimal parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final Enum<?> parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public void setParameter(final String parameterName, final String parameterValue) {
executionParameters.setParameter(parameterName, parameterValue);
}
@Programmatic
public List<FixtureResult> getResults() {
return fixtureResultList.getResults();
}
/**
* @deprecated - use {@link #addResult(FixtureScript, Object)} instead.
*/
@Deprecated
@Programmatic
public <T> T add(final FixtureScript script, final T object) {
return addResult(script, object);
}
@Programmatic
public <T> T addResult(final FixtureScript script, final T object) {
fixtureResultList.add(script, object);
return object;
}
/**
* @deprecated - use {@link #addResult(FixtureScript, String, Object)} instead.
*/
@Programmatic
@Deprecated
public <T> T add(final FixtureScript script, final String key, final T object) {
return addResult(script, key, object);
}
@Programmatic
public <T> T addResult(final FixtureScript script, final String key, final T object) {
fixtureResultList.add(script, key, object);
return object;
}
@Programmatic
public <T> T lookup(final String key, final Class<T> cls) {
return fixtureResultList.lookup(key, cls);
}
/**
* Executes a child {@link FixtureScript fixture script}, injecting services into it first, and (for any results
* that are {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#addResult(FixtureScript, Object)} added),
* uses a key that is derived from the fixture's class name.
*/
@Programmatic
public void executeChild(final FixtureScript callingFixtureScript, final FixtureScript childFixtureScript) {
executeChildT(callingFixtureScript, childFixtureScript);
}
/**
* Executes a child {@link FixtureScript fixture script}, injecting services into it first, and (for any results
* that are {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#addResult(FixtureScript, Object)} added),
* uses a key that is derived from the fixture's class name.
*
* @return the child fixture script.
*/
@Programmatic
public <T extends FixtureScript> T executeChildT(final FixtureScript callingFixtureScript, final T childFixtureScript) {
return executeChildT(callingFixtureScript, null, childFixtureScript);
}
/**
* Executes a child {@link FixtureScript fixture script}, injecting services into it first, and (for any results
* that are {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#addResult(FixtureScript, Object)} added),
* uses a key that overriding the default name of the fixture script with one more meaningful in the context of this fixture.
*/
@Programmatic
public void executeChild(final FixtureScript callingFixtureScript, final String localNameOverride, final FixtureScript childFixtureScript) {
executeChildT(callingFixtureScript, localNameOverride, childFixtureScript);
}
/**
* Executes a child {@link FixtureScript fixture script}, injecting services into it first, and (for any results
* that are {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#addResult(FixtureScript, Object)} added),
* uses a key that overriding the default name of the fixture script with one more meaningful in the context of this fixture.
*
* @return the child fixture script.
*/
@Programmatic
public <T extends FixtureScript> T executeChildT(final FixtureScript callingFixtureScript, final String localNameOverride, final T childFixtureScript) {
childFixtureScript.setParentPath(callingFixtureScript.pathWith(""));
childFixtureScript.withTracing(callingFixtureScript.tracePrintStream); // cascade down
if(localNameOverride != null) {
childFixtureScript.setLocalName(localNameOverride);
}
callingFixtureScript.getContainer().injectServicesInto(childFixtureScript);
executeChildIfNotAlready(childFixtureScript);
return childFixtureScript;
}
static enum As { EXEC, SKIP }
/**
* DO <i>NOT</i> CALL DIRECTLY; instead use {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#executeChild(org.apache.isis.applib.fixturescripts.FixtureScript, String, org.apache.isis.applib.fixturescripts.FixtureScript)} or {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#executeChild(FixtureScript, FixtureScript)}.
*
* @deprecated - should not be called directly, but has <code>public</code> visibility so there is scope for confusion. Replaced by method with private visibility.
*/
@Deprecated
@Programmatic
public void executeIfNotAlready(final FixtureScript fixtureScript) {
executeChildIfNotAlready(fixtureScript);
}
private void executeChildIfNotAlready(final FixtureScript fixtureScript) {
if(shouldExecute(fixtureScript)) {
trace(fixtureScript, As.EXEC);
fixtureScript.execute(this);
} else {
trace(fixtureScript, As.SKIP);
}
}
//region > previouslyExecuted
/**
* Always populated, irrespective of {@link FixtureScripts#getMultipleExecutionStrategy() execution strategy},
* but used only by {@link FixtureScripts.MultipleExecutionStrategy#EXECUTE_ONCE_BY_VALUE} to determine whether
* should execute or not.
*/
private final List<FixtureScript> previouslyExecuted = Lists.newArrayList();
/**
* Returns a list of the {@link FixtureScript} instances that have already been executed.
*
* <p>
* This allows each individual {@link FixtureScript} to determine whether they need to execute; the
* {@link FixtureScripts#getMultipleExecutionStrategy()} can then be left as simply
* {@link FixtureScripts.MultipleExecutionStrategy#EXECUTE}.
* </p>
*/
@Programmatic
public List<FixtureScript> getPreviouslyExecuted() {
return Collections.unmodifiableList(previouslyExecuted);
}
//endregion
//region > shouldExecute
private boolean shouldExecute(final FixtureScript fixtureScript) {
final boolean previouslyExecuted = this.previouslyExecuted.contains(fixtureScript);
if(!previouslyExecuted) {
this.previouslyExecuted.add(fixtureScript);
}
final FixtureScripts.MultipleExecutionStrategy executionStrategy =
fixtureScripts.getMultipleExecutionStrategy();
switch (executionStrategy) {
case IGNORE:
case EXECUTE_ONCE_BY_CLASS:
return shouldExecuteForExecuteOnceByClassStrategy(fixtureScript);
case EXECUTE_ONCE_BY_VALUE:
return !previouslyExecuted;
case EXECUTE:
return true;
default:
throw new IllegalArgumentException("Execution strategy: '" + executionStrategy + "' not recognized");
}
}
/**
* used and populated only if the {@link FixtureScripts.MultipleExecutionStrategy#EXECUTE_ONCE_BY_CLASS}
* strategy is in use.
*/
private final Map<String,Class> fixtureScriptClasses = Maps.newLinkedHashMap();
private boolean shouldExecuteForExecuteOnceByClassStrategy(final FixtureScript fixtureScript) {
final boolean alreadyExecuted = fixtureScriptClasses.values().contains(fixtureScript.getClass());
if(!alreadyExecuted) {
fixtureScriptClasses.put(fixtureScript.getQualifiedName(), fixtureScript.getClass());
}
return !alreadyExecuted;
}
//endregion
//region > tracing
private int traceHighwatermark = 40;
private PrintStream tracePrintStream;
@Programmatic
public ExecutionContext withTracing(final PrintStream tracePrintStream) {
this.tracePrintStream = tracePrintStream;
return this;
}
private void trace(final FixtureScript fixtureScript, final As as) {
if(tracePrintStream == null) {
return;
}
final String qualifiedName = fixtureScript.getQualifiedName();
final String trace = String.format("%1s: %2s %3s\n", pad(qualifiedName), as, fixtureScript.getClass().getName());
tracePrintStream.print(trace);
tracePrintStream.flush();
}
void trace(final FixtureResult fixtureResult) {
if(tracePrintStream == null) {
return;
}
final String key = fixtureResult.getKey();
final String trace = String.format("%1s: %2s\n", pad(key), fixtureScripts.titleOf(fixtureResult));
tracePrintStream.print(trace);
tracePrintStream.flush();
}
private String pad(final String key) {
traceHighwatermark = Math.max(key.length(), traceHighwatermark);
return pad(key, roundup(traceHighwatermark, 20));
}
//endregion
private static String pad(final String str, final int padTo) {
return Strings.padEnd(str, padTo, ' ');
}
static int roundup(final int n, final int roundTo) {
return ((n / roundTo) + 1) * roundTo;
}
private Map<Class, Object> userData = Maps.newHashMap();
@Programmatic
public void setUserData(final Object object) {
userData.put(object.getClass(), object);
}
@Programmatic
public <T> T getUserData(final Class<T> cls) {
return (T) userData.get(cls);
}
@Programmatic
public <T> T clearUserData(final Class<T> cls) {
return (T) userData.remove(cls);
}
}
//endregion
//region > defaultParam, checkParam
protected <T> T defaultParam(final String parameterName, final ExecutionContext ec, final T defaultValue) {
final T value = valueFor(parameterName, ec, defaultValue);
setParam(parameterName, value);
return value;
}
private <T> T valueFor(final String parameterName, final ExecutionContext ec, final T defaultValue) {
final Class<T> cls = (Class<T>) defaultValue.getClass();
final T value = readParam(parameterName, ec, cls);
if(value != null) { return (T) value; }
// else default value
return defaultValue;
}
protected <T> T checkParam(final String parameterName, final ExecutionContext ec, final Class<T> cls) {
final T value = readParam(parameterName, ec, cls);
if(value != null) { return (T) value; }
// else throw exception
throw new IllegalArgumentException(String.format("No value for '%s'", parameterName));
}
private <T> T readParam(final String parameterName, final ExecutionContext ec, final Class<T> cls) {
// read from ExecutionContext
T value = ec.getParameterAsT(parameterName, cls);
if(value != null) { return (T) value; }
// else from fixture script
Method method;
try {
method = this.getClass().getMethod("get" + uppercase(parameterName));
value = (T)method.invoke(this);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored) {
}
if(value != null) { return (T) value; }
if (cls == Boolean.class || cls == boolean.class) {
try {
method = this.getClass().getMethod("is" + uppercase(parameterName));
value = (T)method.invoke(this);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored) {
}
if(value != null) { return (T) value; }
}
return null;
}
private <T> void setParam(final String parameterName, final T value) {
final String mutator = "set" + uppercase(parameterName);
final Method[] methods = this.getClass().getMethods();
for (Method method : methods) {
if(method.getName().equals(mutator) && method.getParameterTypes().length == 1) {
try {
method.invoke(this, value);
} catch (InvocationTargetException | IllegalAccessException ignored) {
}
break;
}
}
}
private String uppercase(final String parameterName) {
return parameterName.substring(0, 1).toUpperCase() + parameterName.substring(1);
}
//endregion
//region > run (entry point for FixtureScripts service to call)
/**
* It's a bit nasty to hold onto this as a field, but required in order to support
*/
private ExecutionContext executionContext;
/**
* Entry point for {@link org.apache.isis.applib.fixturescripts.FixtureScripts} service to call.
*
* <p>
* DO <i>NOT</i> CALL DIRECTLY.
* </p>
*/
@Programmatic
public final List<FixtureResult> run(final String parameters) {
executionContext = fixtureScripts.newExecutionContext(parameters).withTracing(this.tracePrintStream);
executionContext.executeChildIfNotAlready(this);
return executionContext.getResults();
}
/**
* Use instead {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#lookup(String, Class)} directly.
*/
@Programmatic
@Deprecated
public <T> T lookup(final String key, final Class<T> cls) {
if(executionContext == null) {
throw new IllegalStateException("This fixture has not yet been run.");
}
return executionContext.lookup(key, cls);
}
/**
* Optional hook to validate parameters.
*/
@Programmatic
public String validateRun(final String parameters) {
return null;
}
//endregion
//region > executeChild (API for subclasses to call); deprecated execute(FixtureScript, ExecutionContext)
/**
* @deprecated - use instead {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#executeChild(FixtureScript, String, FixtureScript)}.
*/
@Deprecated
protected void execute(
final String localNameOverride,
final FixtureScript childFixtureScript,
final ExecutionContext executionContext) {
executionContext.executeChild(this, localNameOverride, childFixtureScript);
}
/**
* @deprecated - use instead {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#executeChild(FixtureScript, String, FixtureScript)}.
*/
@Deprecated
protected void executeChild(
final String localNameOverride,
final FixtureScript childFixtureScript,
final ExecutionContext executionContext) {
executionContext.executeChild(this, localNameOverride, childFixtureScript);
}
/**
* @deprecated - use instead {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#executeChild(org.apache.isis.applib.fixturescripts.FixtureScript, org.apache.isis.applib.fixturescripts.FixtureScript)}
*/
@Deprecated
protected void execute(
final FixtureScript childFixtureScript,
final ExecutionContext executionContext) {
executionContext.executeChild(this, childFixtureScript);
}
/**
* @deprecated - use instead {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#executeChild(org.apache.isis.applib.fixturescripts.FixtureScript, org.apache.isis.applib.fixturescripts.FixtureScript)}
*/
@Deprecated
protected void executeChild(
final FixtureScript childFixtureScript,
final ExecutionContext executionContext) {
executionContext.executeChild(this, childFixtureScript);
}
//endregion
//region > execute (API for subclasses to implement)
/**
* Subclasses should <b>implement this</b> but SHOULD <i>NOT</i> CALL DIRECTLY.
*
* <p>
* Instead call sub fixture scripts using {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#executeChild(org.apache.isis.applib.fixturescripts.FixtureScript, org.apache.isis.applib.fixturescripts.FixtureScript)} or {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#executeChild(org.apache.isis.applib.fixturescripts.FixtureScript, String, org.apache.isis.applib.fixturescripts.FixtureScript)}.
* </p>
*/
@Programmatic
protected abstract void execute(final ExecutionContext executionContext);
//endregion
//region > (legacy) InstallableFixture impl
@Override
@Programmatic
public FixtureType getType() {
return FixtureType.DOMAIN_OBJECTS;
}
@Programmatic
public final void install() {
run(null);
}
//endregion
//region > helpers (for subclasses)
/**
* Returns the first non-null vaulue; for convenience of subclass implementations
*/
protected static <T> T coalesce(final T... ts) {
for (final T t : ts) {
if(t != null) return t;
}
return null;
}
/**
* Wraps domain object
*/
protected <T> T wrap(final T domainObject) {
return wrapperFactory.wrap(domainObject);
}
protected <T> T wrap(final T domainObject, final WrapperFactory.ExecutionMode executionMode) {
return wrapperFactory.wrap(domainObject, executionMode);
}
/**
* Unwraps domain object (no-arg if already wrapped).
*/
protected <T> T unwrap(final T possibleWrappedDomainObject) {
return wrapperFactory.unwrap(possibleWrappedDomainObject);
}
/**
* Convenience method
*/
protected <T> T mixin(final Class<T> mixinClass, final Object mixedIn) {
return container.mixin(mixinClass, mixedIn);
}
/**
* Convenience method
*/
protected void nextTransaction() {
transactionService.nextTransaction();
}
//endregion
//region > helpers (local)
@Programmatic
String pathWith(final String subkey) {
return (getQualifiedName() != null? getQualifiedName() + PATH_SEPARATOR: "") + subkey;
}
//endregion
//region > injected services
@javax.inject.Inject
protected FixtureScripts fixtureScripts;
@javax.inject.Inject
protected DomainObjectContainer container;
@javax.inject.Inject
protected WrapperFactory wrapperFactory;
@javax.inject.Inject
protected TransactionService transactionService;
//endregion
}