/************************************************************************** OmegaT - Computer Assisted Translation (CAT) tool with fuzzy matching, translation memory, keyword search, glossaries, and translation leveraging into updated projects. Copyright (C) 2000-2006 Keith Godfrey and Maxym Mykhalchuk 2008 Alex Buloichik 2012 Didier Briel 2015 Aaron Madlon-Kay Home page: http://www.omegat.org/ Support center: http://groups.yahoo.com/group/OmegaT/ This file is part of OmegaT. OmegaT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OmegaT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. **************************************************************************/ package org.omegat.core.threads; import java.text.DateFormat; import java.util.Date; import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; import org.omegat.core.Core; import org.omegat.core.KnownException; import org.omegat.core.data.IProject; import org.omegat.util.Preferences; /** * An independent stream to save project, created in order not to freese UI * while project is saved (may take a lot) * * @author Keith Godfrey * @author Alex Buloichik (alex73mail@gmail.com) * @author Didier Briel * @author Aaron Madlon-Kay */ public class SaveThread extends Thread implements IAutoSave { private static final Logger LOGGER = Logger.getLogger(SaveThread.class.getName()); /** The length the thread should wait in milliseconds */ private int waitDuration; private boolean needToSaveNow; private boolean enabled; public SaveThread() { setName("Save thread"); setWaitDuration(Preferences.getPreferenceDefault(Preferences.AUTO_SAVE_INTERVAL, Preferences.AUTO_SAVE_DEFAULT)); Preferences.addPropertyChangeListener(Preferences.AUTO_SAVE_INTERVAL, evt -> { setWaitDuration((Integer) evt.getNewValue()); synchronized (SaveThread.this) { SaveThread.this.notify(); } }); } private void setWaitDuration(int seconds) { waitDuration = seconds * 1000; } public synchronized void disable() { LOGGER.fine("Disable autosave"); enabled = false; } public synchronized void enable() { LOGGER.fine("Enable autosave"); enabled = true; needToSaveNow = false; notify(); } @Override public void run() { try { while (true) { synchronized (this) { // Set flag for saving. If somebody will reset time, he will // clear this flag also. needToSaveNow = true; // sleep wait(waitDuration); } if (needToSaveNow && enabled) { // Wait finished by time and autosaving enabled. IProject dataEngine = Core.getProject(); LOGGER.fine("Start project save from SaveThread"); try { Core.executeExclusively(false, () -> { dataEngine.saveProject(false); try { dataEngine.teamSyncPrepare(); } catch (Exception ex) { LOGGER.log(Level.WARNING, "Error save", ex); } }); Core.getMainWindow().showStatusMessageRB("ST_PROJECT_AUTOSAVED", DateFormat.getTimeInstance(DateFormat.SHORT).format(new Date())); } catch (TimeoutException ex) { LOGGER.warning("Lock trying timeout during autosave"); } catch (KnownException ex) { Core.getMainWindow().showStatusMessageRB(ex.getMessage(), ex.getParams()); } LOGGER.fine("Finish project save from SaveThread"); } } } catch (InterruptedException ex) { LOGGER.log(Level.WARNING, "Save thread interrupted", ex); return; } } }