From ceb89bf8c9e1baae913a5f7993b27ab8b88dadd2 Mon Sep 17 00:00:00 2001 From: felmer <felmer> Date: Thu, 25 Oct 2007 12:58:26 +0000 Subject: [PATCH] IDataStructure changed SVN: 2252 --- .../cisd/bds/AbstractDataStructure.java | 50 +++++++- .../cisd/bds/DataStructureLoader.java | 4 +- .../systemsx/cisd/bds/DataStructureV1_0.java | 44 ++++--- .../ch/systemsx/cisd/bds/IDataStructure.java | 27 +++- .../cisd/bds/DataStructureLoaderTest.java | 5 +- .../cisd/bds/DataStructureV1_0Test.java | 119 ++++++++++++------ 6 files changed, 183 insertions(+), 66 deletions(-) diff --git a/bds/source/java/ch/systemsx/cisd/bds/AbstractDataStructure.java b/bds/source/java/ch/systemsx/cisd/bds/AbstractDataStructure.java index dca7be2e5bb..939286081f8 100644 --- a/bds/source/java/ch/systemsx/cisd/bds/AbstractDataStructure.java +++ b/bds/source/java/ch/systemsx/cisd/bds/AbstractDataStructure.java @@ -27,33 +27,77 @@ import ch.systemsx.cisd.bds.storage.IStorage; abstract class AbstractDataStructure implements IDataStructure { protected final IStorage storage; - protected final IDirectory root; + + protected IDirectory root; AbstractDataStructure(IStorage storage) { assert storage != null: "Unspecified storage."; this.storage = storage; + } + + private void mountStorage() + { storage.mount(); root = storage.getRoot(); } + /** + * Asserts that this instance is already opened or created otherwise a {@link IllegalStateException} is thrown. + */ + protected void assertOpenOrCreated() + { + if (root == null) + { + throw new IllegalStateException("Data structure should first be opened or created."); + } + } + + /** + * Validates this data structure and throws {@link DataStructureException} if invalid. + */ + protected abstract void assertValid(); + + /** + * Performs opening specific for the concrete data structure. Will be invoked after the common part of + * {@link #open()} but before validation with {@link #assertValid()}. + */ + protected abstract void performOpening(); + + /** + * Performs closing specific for the concrete data structure. Will be invoked before validation with + * {@link #assertValid()}. + */ + protected abstract void performClosing(); + // // IDataStructure // + + public final void create() + { + mountStorage(); + } - public void load() + public final void open() { + mountStorage(); + performOpening(); Version loadedVersion = Version.loadFrom(root); if (loadedVersion.isBackwardsCompatibleWith(getVersion()) == false) { throw new DataStructureException("Version of loaded data structure is " + loadedVersion + " which is not backward compatible with " + getVersion()); } + assertValid(); } - public void save() + public final void close() { + assertOpenOrCreated(); getVersion().saveTo(root); + performClosing(); + assertValid(); storage.unmount(); } } diff --git a/bds/source/java/ch/systemsx/cisd/bds/DataStructureLoader.java b/bds/source/java/ch/systemsx/cisd/bds/DataStructureLoader.java index 6c23fa41ac0..9f6ddd0e4bd 100644 --- a/bds/source/java/ch/systemsx/cisd/bds/DataStructureLoader.java +++ b/bds/source/java/ch/systemsx/cisd/bds/DataStructureLoader.java @@ -49,7 +49,9 @@ public class DataStructureLoader IStorage storage = createStorage(name); storage.mount(); Version version = Version.loadFrom(storage.getRoot()); - return DataStructureFactory.createDataStructure(storage, version); + IDataStructure dataStructure = DataStructureFactory.createDataStructure(storage, version); + dataStructure.open(); + return dataStructure; } private IStorage createStorage(String name) diff --git a/bds/source/java/ch/systemsx/cisd/bds/DataStructureV1_0.java b/bds/source/java/ch/systemsx/cisd/bds/DataStructureV1_0.java index 5f678739efc..22702846d0c 100644 --- a/bds/source/java/ch/systemsx/cisd/bds/DataStructureV1_0.java +++ b/bds/source/java/ch/systemsx/cisd/bds/DataStructureV1_0.java @@ -57,6 +57,7 @@ public class DataStructureV1_0 extends AbstractDataStructure */ public IDirectory getOriginalData() { + assertOpenOrCreated(); return Utilities.getOrCreateSubDirectory(getDataDirectory(), DIR_ORIGINAL); } @@ -68,6 +69,7 @@ public class DataStructureV1_0 extends AbstractDataStructure */ public IFormattedData getFormatedData() { + assertOpenOrCreated(); if (format == null) { throw new DataStructureException("Couldn't create formated data because of undefined format."); @@ -81,6 +83,7 @@ public class DataStructureV1_0 extends AbstractDataStructure public void setFormat(Format format) { assert format != null : "Unspecified format."; + assertOpenOrCreated(); this.format = format; } @@ -92,6 +95,7 @@ public class DataStructureV1_0 extends AbstractDataStructure */ public ExperimentIdentifier getExperimentIdentifier() { + assertOpenOrCreated(); return ExperimentIdentifier.loadFrom(getMetaDataDirectory()); } @@ -101,6 +105,7 @@ public class DataStructureV1_0 extends AbstractDataStructure public void setExperimentIdentifier(ExperimentIdentifier id) { assert id != null : "Unspecified experiment identifier"; + assertOpenOrCreated(); id.saveTo(getMetaDataDirectory()); } @@ -112,6 +117,7 @@ public class DataStructureV1_0 extends AbstractDataStructure */ public ProcessingType getProcessingType() { + assertOpenOrCreated(); return ProcessingType.loadFrom(getMetaDataDirectory()); } @@ -121,34 +127,21 @@ public class DataStructureV1_0 extends AbstractDataStructure public void setProcessingType(ProcessingType type) { assert type != null : "Unspecified processing type."; + assertOpenOrCreated(); type.saveTo(getMetaDataDirectory()); } - /** - * Loads the data structure from the storage and sets the format. - */ - @Override - public void load() - { - super.load(); - setFormat(Format.loadFrom(getMetaDataDirectory())); - } - @Override - public void save() + protected void assertValid() { if (getOriginalData().iterator().hasNext() == false) { throw new DataStructureException("Empty original data directory."); } IDirectory metaDataDirectory = getMetaDataDirectory(); - if (metaDataDirectory.tryToGetNode(Format.FORMAT_DIR) == null) + if (metaDataDirectory.tryToGetNode(Format.FORMAT_DIR) == null && format == null) { - if (format == null) - { - throw new DataStructureException("Unspecified format."); - } - format.saveTo(metaDataDirectory); + throw new DataStructureException("Unspecified format."); } if (metaDataDirectory.tryToGetNode(ExperimentIdentifier.FOLDER) == null) { @@ -158,7 +151,22 @@ public class DataStructureV1_0 extends AbstractDataStructure { throw new DataStructureException("Unspecified processing type."); } - super.save(); + } + + @Override + protected void performOpening() + { + setFormat(Format.loadFrom(getMetaDataDirectory())); + } + + @Override + protected void performClosing() + { + IDirectory metaDataDirectory = getMetaDataDirectory(); + if (metaDataDirectory.tryToGetNode(Format.FORMAT_DIR) == null && format != null) + { + format.saveTo(metaDataDirectory); + } } private IDirectory getDataDirectory() diff --git a/bds/source/java/ch/systemsx/cisd/bds/IDataStructure.java b/bds/source/java/ch/systemsx/cisd/bds/IDataStructure.java index c7dbd88c5ca..cfa80e22a7f 100644 --- a/bds/source/java/ch/systemsx/cisd/bds/IDataStructure.java +++ b/bds/source/java/ch/systemsx/cisd/bds/IDataStructure.java @@ -18,20 +18,37 @@ package ch.systemsx.cisd.bds; /** - * Common interface of all data structures. + * Common interface of all data structures. Implementations of this interface provide methods to manipulate a data + * structure. These methods are specific for the version of the data structure. For each version there is a concrete + * class implementing this interface. + * <p> + * A data structure must first be created with {@link #create()} or opened with {@link #open()} before any other method + * can be invoked. An {@link IllegalStateException} is thrown otherwise. Finally a data structure has to be closed with + * {@link #close()} in order to commit all changes made since creation or opening. * * @author Franz-Josef Elmer */ public interface IDataStructure extends IHasVersion { /** - * Loads the data structure. + * Creates a new empty data structure. */ - public void load(); + public void create(); + + /** + * Opens an existing data structure and validates it. + * + * @throws DataStructureException if the data structure is invalid. + */ + public void open(); /** - * Saves the data structure. + * Closes the data structure. Before the data structure is closed it will be validated. + * + * @throws DataStructureException if the data structure is invalid. + * @throws IllegalStateException if called before the first invocation of either {@link #create()} or + * {@link #open()}. */ - public void save(); + public void close(); } \ No newline at end of file diff --git a/bds/sourceTest/java/ch/systemsx/cisd/bds/DataStructureLoaderTest.java b/bds/sourceTest/java/ch/systemsx/cisd/bds/DataStructureLoaderTest.java index f37ebc2fdfd..dad5c33423c 100644 --- a/bds/sourceTest/java/ch/systemsx/cisd/bds/DataStructureLoaderTest.java +++ b/bds/sourceTest/java/ch/systemsx/cisd/bds/DataStructureLoaderTest.java @@ -43,17 +43,18 @@ public class DataStructureLoaderTest } @Test - public void testLoad() + public void testOpen() { File dir = new File(TEST_DIR, "ds"); assert dir.mkdir(); DataStructureV1_0 dataStructure = new DataStructureV1_0(new FileStorage(dir)); + dataStructure.create(); dataStructure.getOriginalData().addKeyValuePair("answer", "42"); dataStructure.setFormat(UnknownFormat1_0.UNKNOWN_1_0); ExperimentIdentifier experimentIdentifier = new ExperimentIdentifier("g", "p", "e"); dataStructure.setExperimentIdentifier(experimentIdentifier); dataStructure.setProcessingType(ProcessingType.RAW_DATA); - dataStructure.save(); + dataStructure.close(); IDataStructure ds = new DataStructureLoader(TEST_DIR).load("ds"); assertEquals(DataStructureV1_0.class, ds.getClass()); diff --git a/bds/sourceTest/java/ch/systemsx/cisd/bds/DataStructureV1_0Test.java b/bds/sourceTest/java/ch/systemsx/cisd/bds/DataStructureV1_0Test.java index 6e3a03d0c02..deda05911b9 100644 --- a/bds/sourceTest/java/ch/systemsx/cisd/bds/DataStructureV1_0Test.java +++ b/bds/sourceTest/java/ch/systemsx/cisd/bds/DataStructureV1_0Test.java @@ -61,6 +61,7 @@ public class DataStructureV1_0Test @Test public void testGetOriginalData() { + dataStructure.create(); IDirectory dataFolder = dataStructure.getOriginalData(); assertEquals(DataStructureV1_0.DIR_ORIGINAL, dataFolder.getName()); assertEquals(DataStructureV1_0.DIR_DATA, dataFolder.tryToGetParent().getName()); @@ -69,6 +70,7 @@ public class DataStructureV1_0Test @Test public void testGetFormatedData() { + dataStructure.create(); dataStructure.setFormat(UnknownFormat1_0.UNKNOWN_1_0); IFormattedData formatedData = dataStructure.getFormatedData(); assertTrue(formatedData instanceof NoFormattedData); @@ -78,6 +80,7 @@ public class DataStructureV1_0Test @Test public void testGetFormatedDataBeforeInvokingSetVersion() { + dataStructure.create(); try { dataStructure.getFormatedData(); @@ -91,6 +94,7 @@ public class DataStructureV1_0Test @Test public void testSetProcessingType() { + dataStructure.create(); dataStructure.setProcessingType(ProcessingType.COMPUTED_DATA); IDirectory root = storage.getRoot(); IDirectory metaData = Utilities.getSubDirectory(root, DataStructureV1_0.DIR_METADATA); @@ -100,6 +104,7 @@ public class DataStructureV1_0Test @Test public void testSetProcessingTypeTwice() { + dataStructure.create(); dataStructure.setProcessingType(ProcessingType.RAW_DATA); dataStructure.setProcessingType(ProcessingType.COMPUTED_DATA); IDirectory root = storage.getRoot(); @@ -110,6 +115,7 @@ public class DataStructureV1_0Test @Test public void testGetProcessingType() { + dataStructure.create(); dataStructure.setProcessingType(ProcessingType.COMPUTED_DATA); assertEquals(ProcessingType.COMPUTED_DATA, dataStructure.getProcessingType()); } @@ -117,6 +123,7 @@ public class DataStructureV1_0Test @Test public void testGetUnknownProcessingType() { + dataStructure.create(); dataStructure.setProcessingType(ProcessingType.COMPUTED_DATA); IDirectory s = Utilities.getSubDirectory(storage.getRoot(), DataStructureV1_0.DIR_METADATA); s.addKeyValuePair(ProcessingType.PROCESSING_TYPE, "blabla"); @@ -126,6 +133,7 @@ public class DataStructureV1_0Test @Test public void testSetExperimentIdentifier() { + dataStructure.create(); ExperimentIdentifier id = new ExperimentIdentifier("g", "p", "e"); dataStructure.setExperimentIdentifier(id); IDirectory root = storage.getRoot(); @@ -139,6 +147,7 @@ public class DataStructureV1_0Test @Test public void testSetExperimentIdentifierTwice() { + dataStructure.create(); dataStructure.setExperimentIdentifier(new ExperimentIdentifier("a", "b", "c")); ExperimentIdentifier id = new ExperimentIdentifier("g", "p", "e"); dataStructure.setExperimentIdentifier(id); @@ -153,6 +162,7 @@ public class DataStructureV1_0Test @Test public void testGetNonExistingExperimentIdentifier() { + dataStructure.create(); try { dataStructure.getExperimentIdentifier(); @@ -166,6 +176,7 @@ public class DataStructureV1_0Test @Test public void testGetExperimentIdentifier() { + dataStructure.create(); ExperimentIdentifier id = new ExperimentIdentifier("g", "p", "e"); dataStructure.setExperimentIdentifier(id); assertEquals(id, dataStructure.getExperimentIdentifier()); @@ -174,15 +185,17 @@ public class DataStructureV1_0Test @Test public void testGetVersion() { + dataStructure.create(); assertEquals(new Version(1, 0), dataStructure.getVersion()); } @Test - public void testSaveForEmptyData() + public void testCloseForEmptyData() { + dataStructure.create(); try { - dataStructure.save(); + dataStructure.close(); fail("DataStructureException expected."); } catch (DataStructureException e) { @@ -191,12 +204,13 @@ public class DataStructureV1_0Test } @Test - public void testSaveIfNoFormat() + public void testCloseIfNoFormat() { + dataStructure.create(); dataStructure.getOriginalData().addKeyValuePair("answer", "42"); try { - dataStructure.save(); + dataStructure.close(); fail("DataStructureException expected."); } catch (DataStructureException e) { @@ -205,13 +219,14 @@ public class DataStructureV1_0Test } @Test - public void testSaveIfNoExperimentID() + public void testCloseIfNoExperimentID() { + dataStructure.create(); dataStructure.getOriginalData().addKeyValuePair("answer", "42"); dataStructure.setFormat(UnknownFormat1_0.UNKNOWN_1_0); try { - dataStructure.save(); + dataStructure.close(); fail("DataStructureException expected."); } catch (DataStructureException e) { @@ -220,14 +235,15 @@ public class DataStructureV1_0Test } @Test - public void testSaveIfNoProcessingType() + public void testCloseIfNoProcessingType() { + dataStructure.create(); dataStructure.getOriginalData().addKeyValuePair("answer", "42"); dataStructure.setFormat(UnknownFormat1_0.UNKNOWN_1_0); dataStructure.setExperimentIdentifier(new ExperimentIdentifier("g", "p", "e")); try { - dataStructure.save(); + dataStructure.close(); fail("DataStructureException expected."); } catch (DataStructureException e) { @@ -236,8 +252,9 @@ public class DataStructureV1_0Test } @Test - public void testSave() + public void testClose() { + dataStructure.create(); dataStructure.getOriginalData().addKeyValuePair("answer", "42"); dataStructure.setFormat(UnknownFormat1_0.UNKNOWN_1_0); ExperimentIdentifier experimentIdentifier = new ExperimentIdentifier("g", "p", "e"); @@ -245,7 +262,7 @@ public class DataStructureV1_0Test dataStructure.setProcessingType(ProcessingType.RAW_DATA); IDirectory root = storage.getRoot(); - dataStructure.save(); + dataStructure.close(); assertEquals(dataStructure.getVersion(), Version.loadFrom(root)); try { @@ -257,7 +274,7 @@ public class DataStructureV1_0Test } DataStructureV1_0 reloadedDataStructure = new DataStructureV1_0(storage); - reloadedDataStructure.load(); + reloadedDataStructure.open(); assertEquals("42\n", Utilities.getString(reloadedDataStructure.getOriginalData(), "answer")); assertEquals(UnknownFormat1_0.UNKNOWN_1_0, reloadedDataStructure.getFormatedData().getFormat()); assertEquals(experimentIdentifier, reloadedDataStructure.getExperimentIdentifier()); @@ -265,11 +282,16 @@ public class DataStructureV1_0Test } @Test - public void testLoadIfVersionMissing() + public void testOpenIfVersionMissing() { + createExampleDataStructure(); + storage.mount(); + IDirectory root = storage.getRoot(); + root.removeNode(Utilities.getSubDirectory(root, Version.VERSION)); + storage.unmount(); try { - dataStructure.load(); + dataStructure.open(); fail("DataStructureException expected."); } catch (DataStructureException e) { @@ -278,33 +300,34 @@ public class DataStructureV1_0Test } @Test - public void testLoad() + public void testOpen() { - IDirectory root = storage.getRoot(); - new Version(1, 0).saveTo(root); - IDirectory metaData = root.makeDirectory(DataStructureV1_0.DIR_METADATA); - UnknownFormat1_0.UNKNOWN_1_0.saveTo(metaData); - dataStructure.load(); + createExampleDataStructure(); + dataStructure.open(); } @Test - public void testLoadVersion1_1() + public void testOpenVersion1_1() { + createExampleDataStructure(); + storage.mount(); IDirectory root = storage.getRoot(); new Version(1, 1).saveTo(root); - IDirectory metaData = root.makeDirectory(DataStructureV1_0.DIR_METADATA); - UnknownFormat1_0.UNKNOWN_1_0.saveTo(metaData); - dataStructure.load(); + storage.unmount(); + dataStructure.open(); } @Test - public void testLoadVersion2_0() + public void testOpenVersion2_0() { + createExampleDataStructure(); + storage.mount(); IDirectory root = storage.getRoot(); new Version(2, 0).saveTo(root); + storage.unmount(); try { - dataStructure.load(); + dataStructure.open(); fail("DataStructureException expected."); } catch (DataStructureException e) { @@ -314,26 +337,30 @@ public class DataStructureV1_0Test } @Test - public void testLoadWithUnknownFormat1_1() + public void testOpenWithUnknownFormat1_1() { + createExampleDataStructure(); + storage.mount(); IDirectory root = storage.getRoot(); - new Version(1, 0).saveTo(root); - IDirectory metaData = root.makeDirectory(DataStructureV1_0.DIR_METADATA); + IDirectory metaData = Utilities.getSubDirectory(root, DataStructureV1_0.DIR_METADATA); new Format(UnknownFormat1_0.UNKNOWN_1_0.getCode(), new Version(1, 1)).saveTo(metaData); - dataStructure.load(); + storage.unmount(); + dataStructure.open(); assertEquals(UnknownFormat1_0.UNKNOWN_1_0, dataStructure.getFormatedData().getFormat()); } @Test - public void testLoadWithUnknownFormat2_0() + public void testOpenWithUnknownFormat2_0() { + createExampleDataStructure(); + storage.mount(); IDirectory root = storage.getRoot(); - new Version(1, 0).saveTo(root); - IDirectory metaData = root.makeDirectory(DataStructureV1_0.DIR_METADATA); + IDirectory metaData = Utilities.getSubDirectory(root, DataStructureV1_0.DIR_METADATA); new Format(UnknownFormat1_0.UNKNOWN_1_0.getCode(), new Version(2, 0)).saveTo(metaData); + storage.unmount(); try { - dataStructure.load(); + dataStructure.open(); dataStructure.getFormatedData(); fail("DataStructureException expected."); } catch (DataStructureException e) @@ -343,14 +370,32 @@ public class DataStructureV1_0Test } @Test - public void testLoadWithAnotherFormat() + public void testOpenWithAnotherFormat() { + createExampleDataStructure(); + storage.mount(); IDirectory root = storage.getRoot(); - new Version(1, 0).saveTo(root); - IDirectory metaData = root.makeDirectory(DataStructureV1_0.DIR_METADATA); + IDirectory metaData = Utilities.getSubDirectory(root, DataStructureV1_0.DIR_METADATA); new Format("another format", new Version(1,1)).saveTo(metaData); - dataStructure.load(); + storage.unmount(); + dataStructure.open(); assertEquals(UnknownFormat1_0.UNKNOWN_1_0, dataStructure.getFormatedData().getFormat()); } + + private void createExampleDataStructure() + { + storage.mount(); + IDirectory root = storage.getRoot(); + new Version(1, 0).saveTo(root); + IDirectory data = root.makeDirectory(DataStructureV1_0.DIR_DATA); + IDirectory originalDataDir = data.makeDirectory(DataStructureV1_0.DIR_ORIGINAL); + originalDataDir.addKeyValuePair("hello", "world"); + IDirectory metaData = root.makeDirectory(DataStructureV1_0.DIR_METADATA); + new Format(UnknownFormat1_0.UNKNOWN_1_0.getCode(), new Version(2, 0)).saveTo(metaData); + new ExperimentIdentifier("g", "p", "e").saveTo(metaData); + ProcessingType.COMPUTED_DATA.saveTo(metaData); + storage.unmount(); + + } } -- GitLab