package io.katharsis.repository; import io.katharsis.queryParams.QueryParams; import java.io.Serializable; /** * <p> * Base unidirectional repository responsible for operations on relations. All of the methods in this interface have * fieldName field as last parameter. It solves a problem of many relationships between the same resources. * <p> * There are two methods that are used for To-One relationships: * <ul> * <li>setRelation</li> * <li>findOneTarget</li> * </ul> * <p> * There are two methods that are used for To-One relationships: * <ul> * <li>setRelations</li> * <li>addRelation</li> * <li>removeRelation</li> * <li>findManyTargets</li> * </ul> * <p> * The reason why there is more than one method for To-Many relationships manipulation is to prevent * <a href="https://en.wikipedia.org/wiki/Race_condition">race condition</a> situations in which a field could be * changed concurrently by another request. * * @param <T> source class type * @param <T_ID> T class id type * @param <D> target class type * @param <D_ID> D class id type */ public interface RelationshipRepository<T, T_ID extends Serializable, D, D_ID extends Serializable> { int TARGET_TYPE_GENERIC_PARAMETER_IDX = 2; /** * Set a relation defined by a field. targetId parameter can be either in a form of an object or null value, * which means that if there's a relation, it should be removed. It is used only for To-One relationship. * * @param source instance of a source class * @param targetId id of a target resource * @param fieldName name of target's filed */ void setRelation(T source, D_ID targetId, String fieldName); /** * Set a relation defined by a field. TargetIds parameter can be either in a form of an object or null value, * which means that if there's a relation, it should be removed. It is used only for To-Many relationship. * * @param source instance of a source class * @param targetIds ids of a target resource * @param fieldName name of target's filed */ void setRelations(T source, Iterable<D_ID> targetIds, String fieldName); /** * Add a relation to a field. It is used only for To-Many relationship, that is if this method is called, a new * relationship should be added to the set of the relationships. * * @param source instance of source class * @param targetIds ids of the target resource * @param fieldName name of target's field */ void addRelations(T source, Iterable<D_ID> targetIds, String fieldName); /** * Removes a relationship from a set of relationships. It is used only for To-Many relationship. * * @param source instance of source class * @param targetIds ids of the target resource * @param fieldName name of target's field */ void removeRelations(T source, Iterable<D_ID> targetIds, String fieldName); /** * Find a relation's target identifier. It is used only for To-One relationship. * * @param sourceId an identifier of a source * @param fieldName name of target's filed * @param queryParams parameters sent along with the request * @return an identifier of a target of a relation */ D findOneTarget(T_ID sourceId, String fieldName, QueryParams queryParams); /** * Find a relation's target identifiers. It is used only for To-Many relationship. * * @param sourceId an identifier of a source * @param fieldName name of target's filed * @param queryParams parameters sent along with the request * @return identifiers of targets of a relation */ Iterable<D> findManyTargets(T_ID sourceId, String fieldName, QueryParams queryParams); }