Repository.java
package io.github.jonloucks.contracts.api;
import java.util.function.Supplier;
import static io.github.jonloucks.contracts.api.BindStrategy.IF_ALLOWED;
/**
* A repository for multiple contract promisors
* This is an opt-in feature to simplify the managing of many contract bindings.
* 1. Optional feature to register required contracts.
* 2. Optional feature to manage multiple contract bindings.
*/
public interface Repository extends AutoOpen {
/**
* Contract to deliver a Repository factory
*/
Contract<Supplier<Repository>> FACTORY = Contract.create("Repository Factory");
/**
* Store the binding.
* Note: Replacing a Contract already promised in this Repository is forbidden after the Repository is opened.
* If the Repository is not open an existing Promisor can be replaced, otherwise it is forbidden.
* If the Repository is not open, the binding will be applied when repository is opened.
* If the Repository has already been opened the binding is applied immediately
* Note: If never explicitly closed, the order of closing promisors is the reverse order they are stored
* @param contract the contract to be bound
* @param promisor the promisor to be bounded
* @param bindStrategy the config for storing the binding
* @return AutoClose responsible for removing the binding from this Repository
* @param <T> the type of contract deliverable
*/
<T> AutoClose store(Contract<T> contract, Promisor<T> promisor, BindStrategy bindStrategy);
/**
* Store the binding.
* Note: Replacing a Contract already promised in this Repository is forbidden after the Repository is opened.
* If the Repository is not open an existing Promisor can be replaced, otherwise it is forbidden.
* If the Repository is not open, the binding will be applied when repository is opened.
* If the Repository has already been opened the binding is applied immediately
* Note: If never explicitly closed, the order of closing promisors is the reverse order they are stored
* @param contract the contract to be bound
* @param promisor the promisor to be bounded
* @return AutoClose responsible for removing the binding from this Repository
* @param <T> the type of contract deliverable
*/
default <T> AutoClose store(Contract<T> contract, Promisor<T> promisor) {
return store(contract, promisor, IF_ALLOWED);
}
/**
* Keep the binding for the life of the repository
* If the Repository is not open, the binding will be created when repository is opened.
* If the Repository has already been opened the binding is created immediately
* Note: The order of closing promisors is the reverse order they are stored
* @param contract the contract to be bound
* @param promisor the promisor to be bounded
* @param bindStrategy the config for storing the binding
* @param <T> the type of contract deliverable
*/
default <T> void keep(Contract<T> contract, Promisor<T> promisor, BindStrategy bindStrategy) {
//noinspection resource; all repository promises are closed when the repository is closed
store(contract, promisor, bindStrategy);
}
/**
* Keep the binding for the life of the repository
* If the Repository is not open, the binding will be created when repository is opened.
* If the Repository has already been opened the binding is created immediately
* Note: The order of closing promisors is the reverse order they are stored
* @param contract the contract to be bound
* @param promisor the promisor to be bounded
* @param <T> the type of contract deliverable
*/
default <T> void keep(Contract<T> contract, Promisor<T> promisor) {
keep(contract, promisor, IF_ALLOWED);
}
/**
* Check that all requirements have fulfilled
*/
void check();
/**
* Added a required contract
* @param contract the contract to be required
* @param <T> the type of contract deliverable
*/
<T> void require(Contract<T> contract);
}