001package org.cpsolver.ifs.util;
002
003import org.apache.log4j.Logger;
004import org.cpsolver.ifs.assignment.Assignment;
005import org.cpsolver.ifs.model.Model;
006import org.cpsolver.ifs.model.Value;
007import org.cpsolver.ifs.model.Variable;
008import org.cpsolver.ifs.solution.Solution;
009import org.cpsolver.ifs.solver.Solver;
010import org.cpsolver.ifs.termination.TerminationCondition;
011
012/**
013 * Abstract problem saver class.
014 * 
015 * @version IFS 1.3 (Iterative Forward Search)<br>
016 *          Copyright (C) 2006 - 2016 Tomáš Müller<br>
017 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
018 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
019 * <br>
020 *          This library is free software; you can redistribute it and/or modify
021 *          it under the terms of the GNU Lesser General Public License as
022 *          published by the Free Software Foundation; either version 3 of the
023 *          License, or (at your option) any later version. <br>
024 * <br>
025 *          This library is distributed in the hope that it will be useful, but
026 *          WITHOUT ANY WARRANTY; without even the implied warranty of
027 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
028 *          Lesser General Public License for more details. <br>
029 * <br>
030 *          You should have received a copy of the GNU Lesser General Public
031 *          License along with this library; if not see
032 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
033 */
034public abstract class ProblemSaver<V extends Variable<V, T>, T extends Value<V, T>, M extends Model<V,T>> implements Runnable {
035    private Solver<V, T> iSolver = null;
036    private Callback iCallback = null;
037    private TerminationCondition<V, T> iTermination = null;
038
039    /**
040     * Constructor
041     * @param solver current solver
042     */
043    public ProblemSaver(Solver<V, T> solver) {
044        iSolver = solver;
045    }
046
047    /** Solver 
048     * @return current solver
049     **/
050    public Solver<V, T> getSolver() {
051        return iSolver;
052    }
053    
054    /** Solution to be saved 
055     * @return current solution
056     **/
057    protected Solution<V, T> getSolution() {
058        return iSolver.currentSolution();
059    }
060
061    /** Model of the solution 
062     * @return problem model
063     **/
064    @SuppressWarnings("unchecked")
065    public M getModel() {
066        return (M)iSolver.currentSolution().getModel();
067    }
068
069    /** Current assignment 
070     * @return current assignment
071     **/
072    public Assignment<V, T> getAssignment() {
073        return getSolution().getAssignment();
074    }
075
076    /** Save the solution 
077     * @throws Exception thrown when save fails
078     **/
079    public abstract void save() throws Exception;
080
081    /**
082     * Sets callback class
083     * 
084     * @param callback
085     *            method {@link Callback#execute()} is executed when save is
086     *            done
087     */
088    public void setCallback(Callback callback) {
089        iCallback = callback;
090    }
091    
092    /**
093     * Provide termination condition so that the save process can be stopped if needed (optional).
094     */
095    public void setTerminationCondition(TerminationCondition<V, T> termination) {
096        iTermination = termination;
097    }
098    
099    /**
100     * Return termination condition so that the save process can be stopped if needed.
101     */
102    public TerminationCondition<V, T> getTerminationCondition() {
103        return iTermination;
104    }
105
106    @Override
107    public void run() {
108        try {
109            save();
110        } catch (Exception e) {
111            Logger.getLogger(this.getClass()).error(e.getMessage(), e);
112        } finally {
113            if (iCallback != null)
114                iCallback.execute();
115        }
116    }
117}