Context.java
package com.github.dakusui.actionunit.core;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import static com.github.dakusui.actionunit.core.Context.Impl.ONGOING_EXCEPTION;
import static java.util.Objects.requireNonNull;
public interface Context {
Context createChild();
boolean defined(String variableName);
<V> V valueOf(String variableName);
Context assignTo(String variableName, Object value);
void unassign(String variableName);
<T extends Throwable> T thrownException();
default boolean wasExceptionThrown() {
return defined(ONGOING_EXCEPTION);
}
class Impl implements Context {
public static final String ONGOING_EXCEPTION = "ONGOING_EXCEPTION";
private final Map<String, Object> variables = new HashMap<>();
private final Context parent;
public Impl() {
this(null);
}
public Impl(Context parent) {
this.parent = parent;
}
@Override
public Context createChild() {
return new Impl(this);
}
@Override
public boolean defined(String variableName) {
if (this.variables.containsKey(variableName))
return true;
if (this.parent == null)
return false;
return parent.defined(variableName);
}
@SuppressWarnings("unchecked")
@Override
public <V> V valueOf(String variableName) {
if (this.variables.containsKey(requireNonNull(variableName)))
return (V) this.variables.get(variableName);
if (parent == null)
throw new NoSuchElementException(String.format("Variable '%s' is not defined.", variableName));
return parent.valueOf(variableName);
}
@Override
public Context assignTo(String variableName, Object value) {
this.variables.put(variableName, value);
return this;
}
@Override
public void unassign(String variableName) {
this.variables.remove(variableName);
}
@SuppressWarnings("unchecked")
@Override
public <T extends Throwable> T thrownException() {
return (T) this.variables.get(ONGOING_EXCEPTION);
}
@Override
public String toString() {
return String.format("Context:(%s; parent=%s)", variables, parent);
}
}
static Context create() {
return new Impl();
}
}