/*******************************************************************************
* GenPlay, Einstein Genome Analyzer
* Copyright (C) 2009, 2014 Albert Einstein College of Medicine
*
* This program 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.
*
* 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 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/>.
* Authors: Julien Lajugie <julien.lajugie@einstein.yu.edu>
* Nicolas Fourel <nicolas.fourel@einstein.yu.edu>
* Eric Bouhassira <eric.bouhassira@einstein.yu.edu>
*
* Website: <http://genplay.einstein.yu.edu>
******************************************************************************/
package edu.yu.einstein.genplay.core.manager.recording;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import edu.yu.einstein.genplay.core.manager.ProjectFiles;
import edu.yu.einstein.genplay.core.manager.project.ProjectManager;
import edu.yu.einstein.genplay.exception.ExceptionManager;
import edu.yu.einstein.genplay.exception.exceptions.InvalidFileTypeException;
import edu.yu.einstein.genplay.gui.MGDisplaySettings.MGDisplaySettings;
import edu.yu.einstein.genplay.gui.mainFrame.MainFrame;
import edu.yu.einstein.genplay.gui.track.Track;
import edu.yu.einstein.genplay.gui.trackList.TrackListPanel;
import edu.yu.einstein.genplay.util.Utils;
/**
* This class manages the saving and loading processes of the current project.
* @author Nicolas Fourel
*/
public class ProjectRecording {
private File fileToLoad; // The project file to load
private Track[] trackList; // The list of tracks to save
private FileInputStream fis;
private GZIPInputStream gz;
private ObjectInputStream ois; // The input file stream
private ProjectInformation projectInformation; // The project information
private boolean trackListReadyToLoad = false; // Checks if the list of track can be loaded
private boolean mgManagerReadyToLoad = false; // Checks if the multi genome manager can be loaded
private boolean loadingEvent = false; // Checks if the request is for loading or for saving
private String currentProjectPath; // path to the current project
/**
* Creates an instance of {@link ProjectRecording}
*/
protected ProjectRecording() {
ois = null;
projectInformation = null;
trackListReadyToLoad = false;
mgManagerReadyToLoad = false;
loadingEvent = false;
}
/**
* Closes input streams
*/
public void closeStreams() {
try {
ois.close();
} catch (IOException e) {
ExceptionManager.getInstance().caughtException(e);
}
try {
gz.close();
} catch (IOException e) {
ExceptionManager.getInstance().caughtException(e);
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
ExceptionManager.getInstance().caughtException(e);
}
}
ois = null;
gz = null;
fis = null;
}
/**
* @return the fileToLoad
*/
public File getFileToLoad() {
return fileToLoad;
}
/**
* @return the projectInformation
*/
public ProjectInformation getProjectInformation() {
return projectInformation;
}
/**
* Reads the track list object.
* @return a track list
*/
public Track[] getTrackList() {
if (trackListReadyToLoad) {
try {
trackList = (Track[]) ois.readObject();
trackListReadyToLoad = false;
} catch (InvalidClassException e) {
String invalidJREMessage = "<html><center>The project you are trying to load was saved using a Java Runtime Environment (JRE) that is not compatible with the JRE currently installed on your computer.<br/>";
invalidJREMessage += "Please refer to the FAQ page at <a href=\"http://genplay.einstein.yu.edu\">http://genplay.einstein.yu.edu</a> for additional information.</center></html>";
JOptionPane.showMessageDialog(MainFrame.getInstance().getRootPane(), invalidJREMessage, "Invalid Java Runtime Environment", JOptionPane.WARNING_MESSAGE);
e.printStackTrace();
} catch (IOException e) {
ExceptionManager.getInstance().caughtException(e);
} catch (ClassNotFoundException e) {
ExceptionManager.getInstance().caughtException(e);
}
return trackList;
}
return null;
}
/**
* Initializes the manager of the multi genome part
* @throws IOException
* @throws ClassNotFoundException
*/
public void initMultiGenomeManager() throws IOException, ClassNotFoundException {
if (mgManagerReadyToLoad && ProjectManager.getInstance().isMultiGenomeProject()) {
ProjectManager.getInstance().readMultiGenomeObject(ois); // read the multi-genome manager
ois.readObject(); // read the MGDisplaySettings
}
trackListReadyToLoad = true;
}
/**
* Creates/sets chromosome manager object.
* @param inputFile project file
* @throws Exception
*/
public void initObjectInputStream(File inputFile) throws Exception {
fileToLoad = inputFile;
fis = new FileInputStream(inputFile);
initObjectInputStream(fis);
}
/**
* Creates/sets chromosome manager object.
* @param is InputStream object
* @throws Exception
*/
public void initObjectInputStream(InputStream is) throws Exception {
try {
gz = new GZIPInputStream(is);
ois = new ObjectInputStream(gz);
} catch (IOException e) {
// a IOException is likely to be caused by a invalid file type
throw new InvalidFileTypeException();
}
}
/**
* Initializes the project information. It unserializes the first object
* contained in the file that is the information about the project. This
* method must be the first one to be called once the object input stream
* has been created.
* @throws ClassNotFoundException
* @throws IOException
*/
public void initProjectInformation() throws ClassNotFoundException, IOException {
if (ois != null) {
projectInformation = (ProjectInformation) ois.readObject();
}
}
/**
* Initializes the project manager. It unserializes the second object
* contained in the file that is the project manager. This method must be
* the second one to be called once the object input stream has been
* created.
* @throws ClassNotFoundException
* @throws IOException
*/
public void initProjectManager() throws ClassNotFoundException, IOException {
if (ois != null) {
ois.readObject(); // read the project manager
// set the project name to match the file name
if (fileToLoad != null) {
ProjectManager.getInstance().setProjectName(Utils.getFileNameWithoutExtension(new File(fileToLoad.getName())));
}
if (ProjectManager.getInstance().isMultiGenomeProject()) {
mgManagerReadyToLoad = true;
trackListReadyToLoad = false;
} else {
mgManagerReadyToLoad = false;
trackListReadyToLoad = true;
}
}
}
/**
* @return the loadingEvent
*/
public boolean isLoadingEvent() {
return loadingEvent;
}
/**
* Saves the current list of tracks into a file
* @param outputFile file where the project needs to be saved
* @return true if the saving was successful. Returns false otherwise
*/
public boolean saveProject(File outputFile) {
try {
TrackListPanel trackListPanel = MainFrame.getInstance().getTrackListPanel();
// remove all the references to the listener so we don't save them
for (Track currentTrack : trackListPanel.getModel().getTracks()) {
currentTrack.removeTrackListener(trackListPanel);
}
FileOutputStream fos = new FileOutputStream(outputFile);
GZIPOutputStream gz = new GZIPOutputStream(fos);
ObjectOutputStream oos = new ObjectOutputStream(gz);
/*
// there is bug during the serialization with the nimbus LAF if the
// track list is visible
if (UIManager.getLookAndFeel().getID().equalsIgnoreCase("Nimbus")) {
trackListPanel.setViewportView(null);
}
*/
updatesCurrentProjectInformation();
oos.writeObject(projectInformation);
oos.writeObject(ProjectManager.getInstance());
if (ProjectManager.getInstance().isMultiGenomeProject()) {
oos.writeObject(ProjectManager.getInstance().getMultiGenomeProject());
oos.writeObject(MGDisplaySettings.getInstance());
}
oos.writeObject(trackListPanel.getModel().getTracks());
// there is bug during the serialization with the nimbus LAF if the
// track list is visible
if (UIManager.getLookAndFeel().getID().equalsIgnoreCase("Nimbus")) {
trackListPanel.setViewportView(trackListPanel.getJpTrackList());
}
oos.flush();
oos.close();
gz.flush();
gz.close();
fos.flush();
fos.close();
// rebuild the references to the listener
for (Track currentTrack : trackListPanel.getModel().getTracks()) {
currentTrack.addTrackListener(trackListPanel);
}
// ProjectManager.getInstance().getProjectConfiguration().writeConfigurationFile();
// deactivate the configuration file saving
} catch (IOException e) {
ExceptionManager.getInstance().caughtException(Thread.currentThread(), e, "An error occurred while saving the project");
return false;
}
return true;
}
/**
* @param currentProjectPath the currentProjectPath to set
*/
public void setCurrentProjectPath(String currentProjectPath) {
this.currentProjectPath = currentProjectPath;
}
/**
* @param fileToLoad the fileToLoad to set
*/
public void setFileToLoad(File fileToLoad) {
this.fileToLoad = fileToLoad;
}
/**
* @param loadingEvent the loadingEvent to set
*/
public void setLoadingEvent(boolean loadingEvent) {
this.loadingEvent = loadingEvent;
}
/**
* Updates the current information about the project
*/
public void updatesCurrentProjectInformation() {
projectInformation = new ProjectInformation();
projectInformation.setFile(new File(currentProjectPath));
ProjectManager projectManager = ProjectManager.getInstance();
projectInformation.setProjectName(projectManager.getProjectName());
if (projectManager.getProjectScorePrecision() == null) {
// for compatibility with old projects when they were no score precision
projectInformation.setProjectPrecision("Unknown");
} else {
projectInformation.setProjectPrecision(projectManager.getProjectScorePrecision().toString());
}
projectInformation.setProjectGenome(projectManager.getGenomeName());
if (projectManager.isMultiGenomeProject()) {
projectInformation.setProjectType("Multi Genome Project");
} else {
projectInformation.setProjectType("Single Genome Project");
}
GregorianCalendar calendar = new GregorianCalendar();
String currentDate = (calendar.get(Calendar.MONTH) + 1) + "/" + calendar.get(Calendar.DATE) + "/" + calendar.get(Calendar.YEAR);
projectInformation.setProjectDate(currentDate);
// we count the number of non-empty tracks in the track list
TrackListPanel trackListPanel = MainFrame.getInstance().getTrackListPanel();
Integer trackCount = 0;
for (Track currentTrack : trackListPanel.getModel().getTracks()) {
if (currentTrack.getLayers().size() > 0) {
trackCount++;
}
}
projectInformation.setProjectTrackNumber(Integer.toString(trackCount));
if (ProjectFiles.getInstance().isFileDependant()) {
projectInformation.setProjectFiles(ProjectFiles.getInstance().getValidArrayOfFiles());
}
}
}