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.

Reply via email to