    001package org.cpsolver.ifs.assignment.context;
    002
    003import org.cpsolver.ifs.assignment.Assignment;
    004import org.cpsolver.ifs.assignment.InheritedAssignment;
    005import org.cpsolver.ifs.model.Value;
    006import org.cpsolver.ifs.model.Variable;
    007
    008public class AssignmentContextHelper {
    009
    010    /**
    011     * Returns an assignment context associated with the given object. If there is no
    012     * assignment context associated with the object yet, one is created using the
    013     * {@link HasAssignmentContext#createAssignmentContext(Assignment)} method.
    014     * @param source given object
    015     * @param assignment given assignment, also implementing {@link CanHoldContext}
    016     * @return assignment context associated with the given object and the given assignment
    017     */
    018    @SuppressWarnings("unchecked")
    019    public static <V extends Variable<V, T>, T extends Value<V, T>, C extends AssignmentContext> C getContext(HasAssignmentContext<V, T, C> source, Assignment<V, T> assignment) {
    020        if (assignment.getIndex() >= 0 && assignment.getIndex() < CanHoldContext.sMaxSize) {
    021            AssignmentContext[] contexts = ((CanHoldContext)source).getContext();
    022            if (assignment.getIndex() > 0 && assignment instanceof InheritedAssignment) {
    023                long version = ((InheritedAssignment<V, T>)assignment).getVersion();
    024
    025                InheritedAssignmentContextHolder.VersionedContext<C> context = (InheritedAssignmentContextHolder.VersionedContext<C>)contexts[assignment.getIndex()];
    026                if (context == null) {
    027                    context = new InheritedAssignmentContextHolder.VersionedContext<C>();
    028                    contexts[assignment.getIndex()] = context;
    029                }
    030
    031                if (!context.isCurrent(version)) {
    032                    if (source instanceof CanInheritContext && contexts[0] != null)
    033                        context.setContent(((CanInheritContext<V, T, C>)source).inheritAssignmentContext(assignment, (C)contexts[0]), version);
    034                    else
    035                        context.setContent(source.createAssignmentContext(assignment), version);
    036                }
    037
    038                return context.getContent();
    039            } else {
    040                AssignmentContext context = contexts[assignment.getIndex()];
    041                if (context == null) {
    042                    context = source.createAssignmentContext(assignment);
    043                    contexts[assignment.getIndex()] = context;
    044                }
    045                return (C) context;
    046            }
    047        }
    048        return assignment.getAssignmentContext(source.getAssignmentContextReference());
    049    }
    050}