Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use pending file during save #311

Merged
merged 3 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/build.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/bin/sh
export DISPLAY=:99
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &
curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/main/ci-build.sh
sh ci-build.sh
38 changes: 29 additions & 9 deletions src/main/java/org/mastodon/mamut/io/project/MamutProject.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
*/
package org.mastodon.mamut.io.project;

import org.apache.commons.io.FileUtils;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
Expand All @@ -36,6 +38,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
Expand Down Expand Up @@ -333,29 +337,37 @@ public void close() throws IOException

private class WriteToDirectory implements ProjectWriter
{
private final File pendingDirectory;

private WriteToDirectory()
{
pendingDirectory = new File( projectRoot.getParent(), projectRoot.getName() + "_pending" );
if ( !pendingDirectory.exists() )
pendingDirectory.mkdir();
}

@Override
public OutputStream getProjectXmlOutputStream() throws FileNotFoundException
{
return new FileOutputStream( new File( projectRoot, PROJECT_FILE_NAME ) );
return new FileOutputStream( new File( pendingDirectory, PROJECT_FILE_NAME ) );
}

@Override
public OutputStream getRawModelOutputStream() throws FileNotFoundException
{
return new FileOutputStream( new File( projectRoot, RAW_MODEL_FILE_NAME ) );
return new FileOutputStream( new File( pendingDirectory, RAW_MODEL_FILE_NAME ) );
}

@Override
public OutputStream getRawTagsOutputStream() throws FileNotFoundException
{
return new FileOutputStream( new File( projectRoot, RAW_TAGS_FILE_NAME ) );
return new FileOutputStream( new File( pendingDirectory, RAW_TAGS_FILE_NAME ) );
}

@Override
public OutputStream getFeatureOutputStream( final String featureKey ) throws IOException
{
final File featureFolder = new File( projectRoot, FEATURE_FOLDER_NAME );
final File featureFolder = new File( pendingDirectory, FEATURE_FOLDER_NAME );
if ( !featureFolder.exists() )
featureFolder.mkdir();
return new FileOutputStream( new File( featureFolder, featureKey + ".raw" ) );
Expand All @@ -364,27 +376,34 @@ public OutputStream getFeatureOutputStream( final String featureKey ) throws IOE
@Override
public OutputStream getGuiOutputStream() throws IOException
{
return new FileOutputStream( new File( projectRoot, GUI_FILE_NAME ) );
return new FileOutputStream( new File( pendingDirectory, GUI_FILE_NAME ) );
}

@Override
public OutputStream getBackupDatasetXmlOutputStream() throws IOException
{
return new FileOutputStream( new File( projectRoot, BACKUP_DATASET_XML_FILE_NAME ) );
return new FileOutputStream( new File( pendingDirectory, BACKUP_DATASET_XML_FILE_NAME ) );
}

@Override
public void close() throws IOException
{}
{
FileUtils.deleteDirectory( projectRoot );
Files.move( pendingDirectory.toPath(), projectRoot.toPath(), StandardCopyOption.REPLACE_EXISTING );
}
}

private class WriteToZip implements ProjectWriter
{
private final WriteZip zip;

WriteToZip() throws IOException
private final File pendingFile;

private WriteToZip() throws IOException
{
zip = new WriteZip( projectRoot );
String suffix = "_pending";
pendingFile = new File( projectRoot.getParent(), projectRoot.getName() + suffix );
zip = new WriteZip( pendingFile );
}

@Override
Expand Down Expand Up @@ -427,6 +446,7 @@ public OutputStream getBackupDatasetXmlOutputStream() throws IOException
public void close() throws IOException
{
zip.close();
Files.move( pendingFile.toPath(), projectRoot.toPath(), StandardCopyOption.REPLACE_EXISTING );
}
}
}
97 changes: 97 additions & 0 deletions src/test/java/org/mastodon/mamut/io/ProjectSaverTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package org.mastodon.mamut.io;

import ij.ImagePlus;
import net.imagej.ImgPlus;
import net.imagej.axis.Axes;
import net.imagej.axis.AxisType;
import net.imglib2.img.Img;
import net.imglib2.img.array.ArrayImgs;
import net.imglib2.img.display.imagej.ImgToVirtualStack;
import net.imglib2.type.numeric.real.FloatType;
import org.junit.Test;
import org.mastodon.mamut.ProjectModel;
import org.mastodon.mamut.io.project.MamutProject;
import org.mastodon.mamut.model.Model;
import org.mastodon.views.bdv.SharedBigDataViewerData;
import org.scijava.Context;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Objects;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

public class ProjectSaverTest
{
@Test
public void testSaveProjectToZip() throws IOException
{
try (Context context = new Context())
{
Model model = new Model();
Img< FloatType > image = ArrayImgs.floats( 1, 1, 1 );
File mastodonFile = File.createTempFile( "test", ".mastodon" );
ProjectModel appModel = wrapAsAppModel( image, model, context, mastodonFile );
ProjectSaver.saveProject( mastodonFile, appModel );
assertNotNull( mastodonFile );
assertTrue( mastodonFile.exists() );
assertTrue( mastodonFile.isFile() );
assertTrue( mastodonFile.length() > 0 );
assertEquals( mastodonFile, appModel.getProject().getProjectRoot() );

ProjectSaver.saveProject( mastodonFile, appModel ); // Overwrite again
assertTrue( mastodonFile.exists() );
assertTrue( mastodonFile.isFile() );
assertTrue( mastodonFile.length() > 0 );
assertEquals( mastodonFile, appModel.getProject().getProjectRoot() );
}
}

@Test
public void testSaveProjectToDirectory() throws IOException
{
try (Context context = new Context())
{
Model model = new Model();
Img< FloatType > image = ArrayImgs.floats( 1, 1, 1 );
File mastodonDirectory = Files.createTempDirectory( "test" ).toFile();
ProjectModel appModel = wrapAsAppModel( image, model, context, mastodonDirectory );
ProjectSaver.saveProject( mastodonDirectory, appModel );
assertNotNull( mastodonDirectory );
assertTrue( mastodonDirectory.exists() );
assertTrue( mastodonDirectory.isDirectory() );
assertEquals( mastodonDirectory, appModel.getProject().getProjectRoot() );
File[] files = mastodonDirectory.listFiles();
assertNotNull( files );
assertEquals( 6, files.length );

ProjectSaver.saveProject( mastodonDirectory, appModel ); // Overwrite again
assertTrue( mastodonDirectory.exists() );
assertTrue( mastodonDirectory.isDirectory() );
assertEquals( mastodonDirectory, appModel.getProject().getProjectRoot() );
files = mastodonDirectory.listFiles();
assertNotNull( files );
assertEquals( 6, files.length );
}
}

private static ProjectModel wrapAsAppModel( final Img< FloatType > image, final Model model, final Context context, final File file )
throws IOException
{
final SharedBigDataViewerData sharedBigDataViewerData = asSharedBdvDataXyz( image );
MamutProject mamutProject = new MamutProject( file );
File datasetXmlFile = File.createTempFile( "test", ".xml" );
mamutProject.setDatasetXmlFile( datasetXmlFile );
return ProjectModel.create( context, model, sharedBigDataViewerData, mamutProject );
}

private static SharedBigDataViewerData asSharedBdvDataXyz( final Img< FloatType > image1 )
{
final ImagePlus image =
ImgToVirtualStack.wrap( new ImgPlus<>( image1, "image", new AxisType[] { Axes.X, Axes.Y, Axes.Z, Axes.TIME } ) );
return Objects.requireNonNull( SharedBigDataViewerData.fromImagePlus( image ) );
}
}
Loading