/*
* RapidMiner
*
* Copyright (C) 2001-2014 by RapidMiner and the contributors
*
* Complete list of developers available at our web site:
*
* http://rapidminer.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.rapidminer.gui.autosave;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import javax.swing.SwingUtilities;
import com.rapidminer.FileProcessLocation;
import com.rapidminer.Process;
import com.rapidminer.ProcessLocation;
import com.rapidminer.RapidMiner;
import com.rapidminer.RepositoryProcessLocation;
import com.rapidminer.gui.RapidMinerGUI;
import com.rapidminer.gui.processeditor.ProcessEditor;
import com.rapidminer.gui.tools.UpdateQueue;
import com.rapidminer.operator.Operator;
import com.rapidminer.repository.MalformedRepositoryLocationException;
import com.rapidminer.repository.RepositoryLocation;
import com.rapidminer.tools.FileSystemService;
import com.rapidminer.tools.LogService;
import com.rapidminer.tools.XMLException;
/**
* @author Venkatesh Umaashankar
*
*/
public class AutoSave {
private File autoSavedProcessProperties;
private File autoSavedProcess;
private UpdateQueue autoSaveQueue;
private boolean autoSaveEnabled;
private boolean recoveryRequired;
private String locationInfo;
public AutoSave() {
String rapidMinerDir = FileSystemService.getUserRapidMinerDir().getAbsolutePath();
File autosaveDir = new File(rapidMinerDir + "/autosave");
autosaveDir.mkdir();
boolean autoSaveDirExists = autosaveDir.exists();
if (autoSaveDirExists) {
autoSavedProcessProperties = new File(autosaveDir.getAbsolutePath() + "/autosaved_process.properties");
autoSavedProcess = new File(autosaveDir.getAbsolutePath() + "/autosaved_process.xml");
autoSaveQueue = new UpdateQueue("autosave-queue");
autoSaveQueue.start();
this.autoSaveEnabled = true;
} else {
LogService.getRoot().log(Level.INFO, "com.rapidminer.gui.autosave.AutoSave.dir_creation_failed");
this.autoSaveEnabled = false;
}
}
public void onLaunch() {
String processType = null;
String processPath = null;
boolean autoSavedProcessExists = autoSavedProcessProperties.exists();
Properties autoSave = new Properties();
FileInputStream autoSaveConfig = null;
try {
if (autoSavedProcessExists) {
autoSaveConfig = new FileInputStream(autoSavedProcessProperties.getAbsolutePath());
autoSave.load(autoSaveConfig);
processType = autoSave.getProperty("autosave.process.type");
processPath = autoSave.getProperty("autosave.process.path");
if (this.autoSaveEnabled) {
recoveryRequired = askForRecovery(processPath.equals("none") ? "" : processPath);
if (recoveryRequired) {
ProcessLocation autoSaveProcessLocation = new FileProcessLocation(autoSavedProcess);
ProcessLocation actualProcessLocation = null;
if (processType.equals("repository_object")) {
actualProcessLocation = new RepositoryProcessLocation(new RepositoryLocation(processPath));
} else if (processType.equals("file")) {
actualProcessLocation = new FileProcessLocation(new File(processPath));
}
Process process = autoSaveProcessLocation.load(null);
process = new Process(process.getRootOperator().getXML(false));
if (actualProcessLocation != null) {
process.setProcessLocation(actualProcessLocation);
RapidMinerGUI.getMainFrame().setOpenedProcess(process, false, actualProcessLocation.toString());
} else {
RapidMinerGUI.getMainFrame().setProcess(process, true);
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
RapidMinerGUI.getMainFrame().SAVE_ACTION.setEnabled(true);
}
});
}
}
}
} catch (IOException e) {
LogService.getRoot().log(Level.WARNING, "com.rapidminer.gui.autosave.AutoSave.load_process_failed", e);
this.autoSaveEnabled = false;
} catch (MalformedRepositoryLocationException e) {
LogService.getRoot().log(Level.WARNING, "com.rapidminer.gui.autosave.AutoSave.load_process_failed", e);
this.autoSaveEnabled = false;
} catch (XMLException e) {
LogService.getRoot().log(Level.WARNING, "com.rapidminer.gui.autosave.AutoSave.load_process_failed", e);
this.autoSaveEnabled = false;
} finally {
if (autoSaveConfig != null) {
try {
autoSaveConfig.close();
} catch (IOException e) {}
}
}
RapidMinerGUI.getMainFrame().addProcessEditor(new ProcessEditor() {
@Override
public void setSelection(List<Operator> selection) {
// do nothing
}
@Override
public void processUpdated(Process process) {
saveProcess(process);
}
@Override
public void processChanged(Process process) {
saveProcess(process);
}
});
RapidMiner.addShutdownHook(new Runnable() {
@Override
public void run() {
AutoSave.this.onShutdown();
}
});
}
private void saveProcess(final Process process) {
if (autoSaveEnabled) {
this.autoSaveQueue.execute(new Runnable() {
@Override
public void run() {
ProcessLocation processLocation = process.getProcessLocation();
if (processLocation != null) {
if (processLocation instanceof FileProcessLocation) {
locationInfo = "autosave.process.type=file" + "\n" + "autosave.process.path=" + ((FileProcessLocation) processLocation).getFile().getAbsolutePath();
} else if (processLocation instanceof RepositoryProcessLocation) {
locationInfo = "autosave.process.type=repository_object" + "\n" + "autosave.process.path=" + ((RepositoryProcessLocation) processLocation).getRepositoryLocation().getAbsoluteLocation();
}
} else {
//process is not saved yet
locationInfo = "autosave.process.type=none" + "\n" + "autosave.process.path=none";
}
String processXML = process.getRootOperator().getXML(false);
try {
FileWriter infoWriter = new FileWriter(autoSavedProcessProperties);
infoWriter.write(locationInfo);
infoWriter.flush();
infoWriter.close();
FileWriter processWriter = new FileWriter(autoSavedProcess);
processWriter.write(processXML);
processWriter.flush();
processWriter.close();
} catch (IOException e) {
LogService.getRoot().log(Level.INFO, "com.rapidminer.gui.autosave.AutoSave.dir_creation_failed", e);
AutoSave.this.autoSaveEnabled = false;
}
}
});
}
}
private boolean askForRecovery(String processPath) {
RecoverDialog recoverDialog = new RecoverDialog(processPath);
recoverDialog.setVisible(true);
int result = recoverDialog.getReturnOption();
return result == RecoverDialog.YES_OPTION;
}
public void onShutdown() {
if (autoSaveEnabled) {
if (autoSavedProcessProperties.exists()) {
autoSavedProcessProperties.delete();
}
if (autoSavedProcess.exists()) {
autoSavedProcess.delete();
}
}
}
}