Action.java
package au.com.mountainpass.hyperstate.core;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import org.springframework.http.HttpMethod;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Predicates;
import com.google.common.collect.Maps;
/**
* Actions represent available behaviours an entity exposes.
*
* @param <T>
* the type returned by invoking the action
*/
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
public abstract class Action<T> extends Labelled {
private String identifier;
private Link link;
private final List<Parameter> parameters = new ArrayList<>();
private Resolver resolver;
protected Action() {
}
public Action(final Resolver resolver, final String identifier, final Link link,
final Parameter... parameters) {
this.identifier = identifier;
this.parameters.addAll(Arrays.asList(parameters));
this.link = link;
this.resolver = resolver;
}
abstract protected CompletableFuture<T> doInvoke(Resolver resolver,
Map<String, Object> filteredParameters);
@JsonProperty("href")
public URI getAddress() {
if (getLink() != null) {
return getLink().getAddress();
} else {
return null;
}
}
/**
* @return the identifier
*/
@JsonProperty("name")
public String getIdentifier() {
return identifier;
}
@JsonIgnore
public Link getLink() {
return this.link;
}
/**
* @return the nature
*/
@JsonProperty("method")
public abstract HttpMethod getNature();
public Set<String> getParameterKeys() {
final Set<String> rval = new HashSet<>();
for (final Parameter param : getParameters()) {
rval.add(param.getIdentifier());
}
return rval;
}
/**
* @return the parameters
*/
@JsonProperty("fields")
public List<Parameter> getParameters() {
return parameters;
}
/**
*
* @param context
* name value pairs representing the parameters the action is being invoked with
* @return a future representing the result from a successful invocation of the action. The
* invocation may be a network operation, so the caller should not make assumptions about
* the timeliness of the response.
*/
public CompletableFuture<T> invoke(final Map<String, Object> context) {
final Set<String> parameterKeys = getParameterKeys();
final Map<String, Object> filteredParameters = new HashMap<>(
Maps.filterKeys(context, Predicates.in(parameterKeys)));
final String id = getIdentifier();
filteredParameters.put("action", id);
return doInvoke(resolver, filteredParameters);
}
}