/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.statcato.file;
import org.statcato.*;
import org.statcato.spreadsheet.*;
import org.statcato.utils.HelperFunctions;
import org.statcato.utils.SetProjectAutoSaveTimer;
import org.statcato.graph.StatcatoChartFrame;
import org.statcato.graph.StatcatoMultipleChartFrame;
import org.jfree.chart.JFreeChart;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.EOFException;
import java.util.zip.GZIPOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.ArrayList;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JFrame;
/**
* A project file that stores the LogWindow instance, DatasheetTabbedPane
* instance,as well as generated charts of this application.
*
* @author Margaret Yau
* @version %I%, %G%
* @since 1.0
*/
public class Project {
private LogWindow Log;
private DatasheetTabbedPane DatasheetPane;
private Statcato app;
private File savedFile;
public static String extension = "stc";
private File tempFile;
private int AUTOSAVEINTERVAL = 300;
private boolean DELETEAUTOSAVEFILE = true;
SetProjectAutoSaveTimer timer;
/**
* Constructor.
*
* @param app Parent Statcato application
*/
public Project(Statcato app) {
this.Log = app.getLogTextPane();
this.DatasheetPane = app.getDatasheetTabbedPane();
this.app = app;
tempFile = new File("~statcato.tmp." +
HelperFunctions.getCurrentTimeString() + ".stc");
// start timer to auto save project periodically
timer = new SetProjectAutoSaveTimer(this, AUTOSAVEINTERVAL);
}
/**
* Sets the auto save interval variable to the given value.
*
* @param seconds number of seconds
*/
public void setAutoSaveInterval(int seconds) {
AUTOSAVEINTERVAL = seconds;
timer.setInterval(seconds);
}
/**
* Sets the delete auto save file boolean to the given value.
*
* @param delete boolean indicating whether to delete auto save file
*/
public void setDeleteAutoSaveFile(boolean delete) {
DELETEAUTOSAVEFILE = delete;
}
/**
* Returns whether this project exists (is valid).
*
* @return whether this project exists (is valid)
*/
public boolean exists() {
return !getName().equals("");
}
/**
* Returns true if the project is modified since the last save.
*
* @return true if the project is modified since the last save or
* false otherwise
*/
public boolean isModified() {
return (Log.getChangedStatus() || DatasheetPane.getChangedStatus());
}
/**
* Writes this project to a file. Opens a file chooser for the user
* to select file for save as or if the project has not been saved before.
*
* @param saveAs whether it is an save as operation
* @return true if the project is saved successfully or false otherwise.
*/
public boolean writeToFile(boolean saveAs) {
String path = "";
if (savedFile != null && !saveAs) { // previously saved in a file
path = savedFile.getPath();
writeFileHelper(path, false);
return true;
}
else {
// create a file chooser
JFileChooser fc = new JFileChooser(
FileOperations.getRecentProject()==
null?null:FileOperations.getRecentProject().getParentFile());
ExtensionFileFilter filter = new ExtensionFileFilter(
"Statcato project file (*.stc)", extension);
fc.addChoosableFileFilter(filter);
fc.setAcceptAllFileFilterUsed(false);
int returnValue = fc.showSaveDialog(app);
if (returnValue == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
path = file.getPath();
if (!path.toLowerCase().endsWith("." + extension)) {
path += "." + extension;
file = new File(path);
}
if (file.exists()) { // file exists already
Object[] options = {"Overwrite file", "Cancel"};
int choice = JOptionPane.showOptionDialog(app,
"The specified file already exists. Overwrite existing file?",
"Overwrite file?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
null, options, options[1]);
if (choice != 0) { // don't overwrite
return false;
}
}
boolean success = writeFileHelper(path, false);
if (!success) {
return false;
}
savedFile = file;
return true;
}
return false;
}
}
/**
* Returns the saved project file.
*
* @return project file
*/
public File getFile() {
return savedFile;
}
/**
* Called by writeToFile function to perform writing of the project file
* to the given file path.
*
* @param path file path
* @paren autoSave whether this is a write for auto save
* @return whether the write was successful
*/
private boolean writeFileHelper(String path, boolean autoSave) {
// write to file
try {
// write log contents
String htmlSource = Log.getText();
String htmlSource2 = "";
if (htmlSource.indexOf("") != -1) {
int start = htmlSource.indexOf("") + 6;
htmlSource = htmlSource.substring(start);
while (htmlSource.contains("")) {
start = htmlSource.indexOf("") + 6;
htmlSource = htmlSource.substring(start);
}
int end = htmlSource.indexOf("");
if (end == -1) {
end = htmlSource.length();
}
htmlSource = htmlSource.substring(0, end);
}
String [] lines = htmlSource.split("\n");
for (int i = 0; i < lines.length; ++i) {
htmlSource2 += lines[i];
}
htmlSource = "\n\n\n\n\n" + htmlSource2 +
"\n\n\n";
FileOutputStream fos = new FileOutputStream(path);
GZIPOutputStream gz = new GZIPOutputStream(fos);
ObjectOutputStream oos = new ObjectOutputStream(gz);
oos.writeObject(htmlSource);
// reset modified status of log
if (!autoSave) {
Log.setUnchangedStatus();
}
// write the number of datasheets
int count = DatasheetPane.getTabCount();
oos.writeObject(new Integer(count));
// write datasheets
for (int i = 0; i < count; ++i) {
Spreadsheet s = ((SpreadsheetScrollPane)
DatasheetPane.getComponentAt(i)).getSpreadsheet();
if (!autoSave) {
s.setUnchangedStatus();
s.closeFile();
}
oos.writeObject(
((SpreadsheetModel)s.getModel()).getTabDelimitedValues());
}
if (!autoSave) {
DatasheetPane.resetTabTitles();
}
count = app.getChartFrames().size();
if (count != 0) {
// write the number of chart objects
oos.writeObject(new Integer(count));
// write chart objects
for (int i = 0; i < count; ++i) {
JFrame frame = app.getChartFrames().get(i);
if (frame instanceof StatcatoChartFrame) {
StatcatoChartFrame chartFrame =
(StatcatoChartFrame) frame;
String title = chartFrame.getChartTitle();
JFreeChart chart = chartFrame.getChart();
try {
oos.writeObject(title);
oos.writeObject("s"); // 's' to indicate single chart frame
oos.writeObject(chart);
}
catch (IOException e) {
System.err.println("fail to write StatcatoChartFrame");
return false;
}
}
else if (frame instanceof StatcatoMultipleChartFrame) {
StatcatoMultipleChartFrame chartFrame =
(StatcatoMultipleChartFrame) frame;
String title = chartFrame.getChartTitle();
ArrayList charts = chartFrame.getCharts();
try {
oos.writeObject(title);
// 'm' to indicate multiple chart frame,
// followed by the number of charts in the frame
oos.writeObject("m" + charts.size());
for (int j = 0; j < charts.size(); ++j) {
oos.writeObject(charts.get(j));
}
}
catch (IOException e) {
System.err.println("fail to write StatcatoMultipleChartFrame");
return false;
}
}
}
}
oos.flush();
oos.close();
gz.close();
fos.close();
return true;
}
catch (IOException e) {
return false;
}
}
/**
* Writes project file to the temporary file path.
*
*/
public void autoSaveWrite() {
if (writeFileHelper(tempFile.getPath(), true)) {
app.restoreStatusTimer(1);
app.setStatus("Auto save completed.");
}
else {
app.restoreStatusTimer(1);
app.setStatus("Auto save failed.");
}
}
/**
* Returns the name of this project.
*
* @return name, or empty string if this project has no name
*/
public String getName() {
if (savedFile == null) {
return "";
}
return savedFile.getName();
}
/**
* Read a project file from the given path. The read log is appended
* to the existing log, and the datasheets are added to the existing
* datasheet pane.
*
* @param path project file path
* @return true if a project file is read successfully, or false otherwise
*/
public boolean readFile(String path) {
try {
FileInputStream fis = new FileInputStream(path);
GZIPInputStream gs = new GZIPInputStream(fis);
ObjectInputStream ois = new ObjectInputStream(gs);
// read log
Object o = ois.readObject();
String htmlSource;
if (o instanceof String) {
htmlSource = (String)o;
}
else {
return false;
}
// read datasheets
int count;
o = ois.readObject();
if (o instanceof Integer) {
count = ((Integer)o).intValue();
}
else {
return false;
}
String[] sheets = new String[count];
for (int i = 0; i < count; ++i) {
o = ois.readObject();
if (o instanceof String) {
String s = (String) o;
sheets[i] = s;
}
else {
return false;
}
}
// read chart titles and objects
ArrayList frames = new ArrayList();
int countCharts = 0;
try {
o = ois.readObject();
if (o != null) {
if (o instanceof Integer) {
countCharts = ((Integer)o).intValue();
}
else {
System.err.println("num charts not an integer");
return false;
}
for (int i = 0; i < countCharts; ++i) {
String title;
// read chart title
try {
o = ois.readObject();
if (o instanceof String) {
title = (String) o;
}
else {
System.err.println("not a chart title");
return false;
}
}
catch (IOException ex) {
System.err.println("failed to read chart title");
return false;
}
// read chart type indicator 's' or 'mx', where x is
// the number of charts
try {
o = ois.readObject();
if (o instanceof String) {
String type = (String) o;
if (type.startsWith("s")) { // single chart
try {
o = ois.readObject();
if (o instanceof JFreeChart) {
frames.add(new StatcatoChartFrame(
title, (JFreeChart) o, app));
}
else {
System.err.println("not a chart object");
return false;
}
}
catch (IOException ex) {
System.err.println("failed to read chart object");
return false;
}
}
else { // multiple charts
int chartCount = Integer.parseInt(type.substring(1));
ArrayList charts =
new ArrayList();
for (int k = 0; k < chartCount; ++k) {
try {
o = ois.readObject();
if (o instanceof JFreeChart) {
charts.add((JFreeChart) o);
}
else {
System.err.println("not a chart object");
return false;
}
}
catch (IOException ex) {
System.err.println("failed to read chart object");
return false;
}
}
frames.add(new StatcatoMultipleChartFrame(title, charts, app));
}
}
else {
System.err.println("not a chart type indicator");
return false;
}
}
catch (IOException ex) {
System.err.println("failed to read chart type indicator");
return false;
}
}
}
}
catch (EOFException e) {
System.err.println("end of file");
}
ois.close();
gs.close();
fis.close();
// close current project
if (close()) {
// write to log and datasheet pane
Log.overwrite(htmlSource);
Log.setUnchangedStatus();
for (int i = 0; i < count; ++i) {
DatasheetPane.addDatasheet(sheets[i], null);
}
// restore chart frames
for (int i = 0; i < frames.size(); ++i) {
JFrame frame = frames.get(i);
app.addWindowFrame(frame);
frame.pack();
frame.setVisible(true);
}
savedFile = new File(path);
return true;
}
return false;
}
catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* If the project is not yet saved, prompts the user to save.
* Closes the open project (log and datasheets).
*
* @return whether the project can be closed.
*/
public boolean close() {
Object[] options = {"Save Project", "Close Without Saving"};
int choice;
// prompt for unsaved files
if (Log.getChangedStatus() || DatasheetPane.getChangedStatus()) {
choice = JOptionPane.showOptionDialog(app,
"This project is not yet saved.",
"Unsaved project...",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, null,
options, options[0]);
if (choice == JOptionPane.CLOSED_OPTION) {
return false;
}
if (choice == 0) {
// save and clear log
if (!writeToFile(false)) {
return false; // save was not successful
}
}
}
Log.clear();
Log.setUnchangedStatus();
DatasheetPane.removeAll();
savedFile = null;
app.removeChartFrames();
return true;
}
/**
* Deletes temporary file if it exists.
*/
public void exit() {
if (DELETEAUTOSAVEFILE) {
tempFile.delete();
}
}
}
Ads help maintain this website.