Author: clopes
Date: 2012-08-22 13:50:01 -0700 (Wed, 22 Aug 2012)
New Revision: 30251
Modified:
core3/impl/trunk/core-task-impl/src/main/java/org/cytoscape/task/internal/session/CySessionWriter.java
core3/impl/trunk/io-impl/impl/src/main/java/org/cytoscape/io/internal/write/session/SessionWriterImpl.java
Log:
Fixes #1382 (Corrupted session files when exception is thrown): Now it saves a
temp file first, and replaces the original one only if the task is completed
with no errors.
Modified:
core3/impl/trunk/core-task-impl/src/main/java/org/cytoscape/task/internal/session/CySessionWriter.java
===================================================================
---
core3/impl/trunk/core-task-impl/src/main/java/org/cytoscape/task/internal/session/CySessionWriter.java
2012-08-22 19:57:59 UTC (rev 30250)
+++
core3/impl/trunk/core-task-impl/src/main/java/org/cytoscape/task/internal/session/CySessionWriter.java
2012-08-22 20:50:01 UTC (rev 30251)
@@ -24,6 +24,7 @@
private File outputFile;
Logger logger = LoggerFactory.getLogger(CySessionWriter.class);
+
/**
* Constructs this CySessionWriter.
* @param writerMgr The {@link
org.cytoscape.io.write.CySessionWriterManager} contains single expected
@@ -32,15 +33,15 @@
* @param outputFile The file the {@link
org.cytoscape.session.CySession} should be written to.
*/
public CySessionWriter(CySessionWriterManager writerMgr, CySession
session, File outputFile) {
- if ( writerMgr == null )
+ if (writerMgr == null)
throw new NullPointerException("Writer Manager is
null");
this.writerMgr = writerMgr;
- if ( session == null )
+ if (session == null)
throw new NullPointerException("Session Manager is
null");
this.session = session;
- if ( outputFile == null )
+ if (outputFile == null)
throw new NullPointerException("Output File is null");
this.outputFile = outputFile;
}
@@ -51,22 +52,32 @@
* @param tm The {@link org.cytoscape.work.TaskMonitor} provided by the
TaskManager execution environment.
*/
public final void run(TaskMonitor tm) throws Exception {
- List<CyFileFilter> filters =
writerMgr.getAvailableWriterFilters();
- if ( filters == null || filters.size() < 1)
+ final List<CyFileFilter> filters =
writerMgr.getAvailableWriterFilters();
+
+ if (filters == null || filters.size() < 1)
throw new NullPointerException("No Session file filters
found");
- if ( filters.size() > 1 )
+ if (filters.size() > 1)
throw new IllegalArgumentException("Found too many
session filters.");
- if (!outputFile.getName().endsWith(".cys")){
+ if (!outputFile.getName().endsWith(".cys")) {
outputFile = new File(outputFile.getPath() + ".cys");
logger.warn("File name is changed to " +
outputFile.getName());
}
- CyWriter writer =
writerMgr.getWriter(session,filters.get(0),outputFile);
- if ( writer == null )
+ // Write to a temporary file first, to prevent the original
file from being damaged, in case there is any error
+ final String filename = outputFile.getName() + ".tmp";
+ final File tmpFile = new
File(System.getProperty("java.io.tmpdir"), filename);
+ tmpFile.deleteOnExit();
+
+ final CyWriter writer = writerMgr.getWriter(session,
filters.get(0), tmpFile);
+
+ if (writer == null)
throw new NullPointerException("No CyWriter found for
specified file type.");
- insertTasksAfterCurrentTask( writer );
+ // If the main task is successfully executed, this task will
move the temp file to the actual output path
+ final ReplaceFileTask replaceFileTask = new
ReplaceFileTask(tmpFile, outputFile);
+
+ insertTasksAfterCurrentTask(writer, replaceFileTask);
}
static boolean HasFileExtension(final String pathName) {
@@ -74,4 +85,30 @@
final int lastSlashPos =
pathName.lastIndexOf(File.separatorChar);
return lastSlashPos < lastDotPos; // Yes, this also works if
one or both of lastSlashPos and lastDotPos are -1!
}
+
+ private class ReplaceFileTask extends AbstractTask {
+ private final File source;
+ private final File target;
+
+ public ReplaceFileTask(final File source, final File target) {
+ this.source = source;
+ this.target = target;
+ }
+
+ @Override
+ public void run(TaskMonitor taskMonitor) throws Exception {
+ boolean success = source.renameTo(target);
+
+ if (success) {
+ try {
+ source.delete();
+ } catch (Exception e) {
+ logger.warn("Cannot delete temp file: "
+ source.getAbsolutePath(), e);
+ }
+ } else {
+ throw new RuntimeException("Session not saved:
Cannot copy temporary file to " +
+ target.getAbsolutePath());
+ }
+ }
+ }
}
Modified:
core3/impl/trunk/io-impl/impl/src/main/java/org/cytoscape/io/internal/write/session/SessionWriterImpl.java
===================================================================
---
core3/impl/trunk/io-impl/impl/src/main/java/org/cytoscape/io/internal/write/session/SessionWriterImpl.java
2012-08-22 19:57:59 UTC (rev 30250)
+++
core3/impl/trunk/io-impl/impl/src/main/java/org/cytoscape/io/internal/write/session/SessionWriterImpl.java
2012-08-22 20:50:01 UTC (rev 30251)
@@ -168,35 +168,78 @@
tm.setProgress(0.0);
tm.setTitle("Writing Session File");
tm.setStatusMessage("Preparing...");
+
+ try {
+ init(tm);
+ write(tm);
+ } finally {
+ complete(tm);
+ }
+
+ tm.setStatusMessage("Done.");
+ tm.setProgress(1.0);
+ }
+
+ private void init(TaskMonitor tm) throws Exception {
zos = new ZipOutputStream(outputStream);
- prepareGroups();
+ prepareGroups(); // Groups require specific metadata
+ }
+
+ private void write(TaskMonitor tm) throws Exception {
zipVersion();
- tm.setStatusMessage("Zip networks...");
tm.setProgress(0.1);
+
+ if (cancelled) return;
+
+ tm.setStatusMessage("Saving networks...");
zipNetworks();
tm.setProgress(0.3);
+
+ if (cancelled) return;
+
+ tm.setStatusMessage("Saving network views...");
zipNetworkViews();
tm.setProgress(0.4);
- tm.setStatusMessage("Zip tables...");
+
+ if (cancelled) return;
+
+ tm.setStatusMessage("Saving tables...");
zipTables();
tm.setProgress(0.5);
- tm.setStatusMessage("Zip table properties...");
+
+ if (cancelled) return;
+
+ tm.setStatusMessage("Saving table properties...");
zipTableProperties();
tm.setProgress(0.6);
- tm.setStatusMessage("Zip Vizmap...");
+
+ if (cancelled) return;
+
+ tm.setStatusMessage("Saving visual styles...");
zipVizmap();
tm.setProgress(0.7);
- tm.setStatusMessage("Zip Cytoscape properties...");
+
+ if (cancelled) return;
+
+ tm.setStatusMessage("Saving Cytoscape properties...");
zipProperties();
tm.setProgress(0.8);
- tm.setStatusMessage("Zip apps...");
+
+ if (cancelled) return;
+
zipFileListMap();
tm.setProgress(0.9);
- zos.close();
- tm.setStatusMessage("Done.");
- tm.setProgress(1.0);
}
-
+
+ private void complete(TaskMonitor tm) {
+ try {
+ if (zos != null)
+ zos.close();
+ } catch (Exception e) {
+ logger.error("Error closing zip output stream", e);
+ }
+ }
+
/**
* Writes the version file, which has no content. The file name itself
gives the CYS version.
*/
--
You received this message because you are subscribed to the Google Groups
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/cytoscape-cvs?hl=en.