package uk.q3c.krail.core.services; import com.google.common.collect.ImmutableList; import javax.annotation.Nonnull; import java.util.List; import java.util.Optional; /** * A wrapper on a Jung graph used specifically for modelling relationships between either {@link Service} classes (represented by a {@link ServiceKey}) or * Service instances in * {@link ServicesModel} * <p> * <p> * <T> is expected to be either {@link ServiceKey} or a {@link Service} instance * <p> * <p> * Created by David Sowerby on 03/12/15. */ public interface ServicesGraph<T> { enum Selection {ONLY_REQUIRED_AT_START, REQUIRED_AT_START, ALWAYS_REQUIRED, OPTIONAL, ALL} /** * Returns a list of dependencies for {@code dependant} which are of the {@link Dependency.Type} defined by {@code selection} * * @param dependant the dependant for which dependencies are requested * @param selection which {@link Dependency.Type}s to select * @return List of vertices on which {@code dependant} depends and meet the selection criteria given by meeting the selection */ List<T> findDependencies(@Nonnull T dependant, @Nonnull Selection selection); List<T> findDependants(@Nonnull T dependency, @Nonnull Selection selection); /** * Adds a service to this graph. Returns true if {@code service} is added, false if not added (because {@code service} is already in the graph) * * @param service the service to be added */ boolean addService(@Nonnull T service); /** * Removes a service from this graph * * @param service the service to be removed */ boolean removeService(@Nonnull T service); boolean contains(@Nonnull T service); /** * Returns the edge (and therefore the dependency type) between two services. If you get the dependant * and dependency the wrong way round the edge will not be found * * @return the edge if found, Optional.empty() if not */ Optional<ServiceEdge> getEdge(@Nonnull T dependant, @Nonnull T dependency); /** * Creates a dependency from {@code dependant} to {@code dependency} of type {@code type} * * @param dependant the Service which depends on {@code dependency}. Will be added to the graph if not already * added. * @param dependency the Service on which {@code dependant} depends. Will be added to the graph if not already * added. * @param type the type of {@link Dependency) * @throws CycleDetectedException if a loop is created by forming this dependency * @throws DuplicateDependencyException if a dependency is created twice between the same Services */ void createDependency(@Nonnull T dependant, @Nonnull T dependency, Dependency.Type type); /** * Returns a list of the services contained ion this graph * * @return a list of the services contained ion this graph */ ImmutableList<T> getServices(); /** * Returns true if {@code dependant} has {@code dependency} * * @return true if {@code dependant} has {@code dependency} */ boolean hasDependency(@Nonnull T dependant, @Nonnull T dependency); /** * Returns true if {@code dependency} has {@code dependant} * * @return true if {@code dependency} has {@code dependant} */ boolean hasDependant(@Nonnull T dependency, @Nonnull T dependant); /** * Returns the number of vertices in the graph * @return the number of vertices in the graph */ int size(); /** * Returns true only if {@code dependency} is an optional dependency of {@code dependant} * * @param dependency the dependency to check * @param dependant the dependant which may have the dependency * @return true if {@code dependency} is an optional dependency of {@code dependant}, false otherwise */ boolean isOptionalDependency(@Nonnull T dependency, @Nonnull T dependant); }