-package org.simantics.databoard.container;\r
-\r
-import java.io.DataInput;\r
-import java.io.DataInputStream;\r
-import java.io.DataOutput;\r
-import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.util.Map;\r
-import java.util.TreeMap;\r
-\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.binding.impl.TreeMapBinding;\r
-import org.simantics.databoard.binding.mutable.Variant;\r
-import org.simantics.databoard.serialization.Serializer;\r
-import org.simantics.databoard.type.Datatype;\r
-import org.simantics.databoard.util.binary.BinaryFile;\r
-\r
-/**\r
- * An utility class for reading files whose format follows\r
- * {@link DataContainer}.\r
- * @author Hannu Niemistö\r
- */\r
-public class DataContainers {\r
-\r
- private static final Serializer STRING_SERIALIZER = \r
- Bindings.getSerializerUnchecked(Bindings.STRING);\r
- private static final Serializer INTEGER_SERIALIZER = \r
- Bindings.getSerializerUnchecked(Bindings.INTEGER);\r
- private static final Serializer METADATA_SERIALIZER = \r
- Bindings.getSerializerUnchecked(new TreeMapBinding(Bindings.STRING, Bindings.VARIANT));\r
- private static final Serializer DATATYPE_SERIALIZER =\r
- Bindings.getSerializerUnchecked(Datatype.class);\r
- private static final Serializer VARIANT_SERIALIZER =\r
- Bindings.getSerializerUnchecked(Bindings.VARIANT);\r
- private static final Serializer DATA_CONTAINER_SERIALIZER =\r
- Bindings.getSerializerUnchecked(DataContainer.class);\r
-\r
- /**\r
- * Binds a format name and a version together to form a format version\r
- * identifier string.\r
- * \r
- * @param formatName\r
- * @param version\r
- * @return\r
- */\r
- public static String toFormatString(String formatName, int version) {\r
- return formatName + ":" + version;\r
- }\r
-\r
- /**\r
- * Reads only the header of the data container. Returns\r
- * a DataContainer whose content-field is null.\r
- * @throws IOException \r
- */\r
- public static DataContainer readHeader(DataInput input) throws IOException {\r
- String format = (String)STRING_SERIALIZER.deserialize(input);\r
- int version = (Integer)INTEGER_SERIALIZER.deserialize(input);\r
- @SuppressWarnings("unchecked")\r
- TreeMap<String,Variant> metadata = (TreeMap<String,Variant>)METADATA_SERIALIZER.deserialize(input); \r
- return new DataContainer(format, version, metadata, null);\r
- }\r
- \r
- /**\r
- * Consumes a header from a given stream and checks that the header satisfies the given format and version.\r
- * Returns the obtained header if the check fails and null on success.\r
- * @throws IOException \r
- */\r
- public static DataContainer requireHeader(DataInput input, String format, int version) {\r
- try {\r
- DataContainer header = readHeader(input);\r
- if(!format.equals(header.format) || version != header.version)\r
- return header;\r
- else return null;\r
- } catch (Throwable t) {\r
- return new DataContainer("unknown", 0, null, null);\r
- }\r
- }\r
-\r
- /**\r
- * Consumes a header from a given stream and checks that the header satisfies the given format and version restrictions.\r
- * Returns the obtained header if the check fails and null on success.\r
- * @throws IOException \r
- */\r
- public static DataContainer requireHeader(DataInput input, String... requiredFormatStrings) {\r
- try {\r
- DataContainer header = readHeader(input);\r
- String formatString = toFormatString(header.format, header.version);\r
- for (String requiredFormatString : requiredFormatStrings) {\r
- if(formatString.equals(requiredFormatString))\r
- return null;\r
- }\r
- return header;\r
- } catch (Throwable t) {\r
- return new DataContainer("unknown", 0, null, null);\r
- }\r
- }\r
-\r
- /**\r
- * Checks that the given file satisfies the given format and version. \r
- * Returns the obtained header if the check fails and null on success.\r
- * @throws IOException \r
- */\r
- public static DataContainer validateHeader(File file, String format, int version) throws IOException {\r
-\r
- InputStream stream = new FileInputStream( file );\r
- try {\r
- return DataContainers.requireHeader(new DataInputStream(stream), format, version);\r
- } finally {\r
- stream.close();\r
- }\r
- \r
- }\r
-\r
- /**\r
- * Checks that the given file satisfies the given format and version. \r
- * Returns the obtained header if the check fails and null on success.\r
- * @throws IOException \r
- */\r
- public static DataContainer validateHeader(File file, String... allowedFormatStrings) throws IOException {\r
-\r
- InputStream stream = new FileInputStream( file );\r
- try {\r
- return DataContainers.requireHeader(new DataInputStream(stream), allowedFormatStrings);\r
- } finally {\r
- stream.close();\r
- }\r
- \r
- }\r
-\r
- /**\r
- * Reads only the header of the data container. Returns\r
- * a DataContainer whose content-field is null.\r
- * @throws IOException \r
- */\r
- public static DataContainer readHeader(File input) throws IOException {\r
- BinaryFile rf = new BinaryFile( input, "r" );\r
- try {\r
- return readHeader(rf);\r
- } finally {\r
- rf.close();\r
- } \r
- }\r
- \r
- /**\r
- * Reads a data container including the content data.\r
- * @throws IOException \r
- */\r
- public static DataContainer readFile(DataInput input) throws IOException {\r
- DataContainer result = readHeader(input);\r
- result.content = (Variant)VARIANT_SERIALIZER.deserialize(input);\r
- return result;\r
- }\r
-\r
- /**\r
- * Process a data container using a format handler matching the format and version\r
- * of the file. \r
- * @param handlers Map of handlers. Keys are strings of form "format:version".\r
- */\r
- public static <T> T readFile(DataInput input, Map<String, FormatHandler<T>> handlers) throws Exception {\r
- DataContainer result = readHeader(input);\r
- \r
- FormatHandler<T> handler = handlers.get(result.format + ":" + result.version);\r
- if(handler == null)\r
- throw new DataFormatException("Unknown data format " + result.format + " version " + result.version + ".");\r
- Binding binding = handler.getBinding();\r
- \r
- Datatype contentType = (Datatype)DATATYPE_SERIALIZER.deserialize(input);\r
- if(!binding.type().equals(contentType))\r
- throw new DataFormatException("Content type didn't match the type expected for the format " + result.format + " version " + result.version + ".");\r
- \r
- Object value = Bindings.getSerializerUnchecked(binding).deserialize(input);\r
- \r
- result.content = new Variant(binding, value);\r
- return handler.process(result);\r
- }\r
- \r
- /**\r
- * Reads a data container including the content data.\r
- * @throws IOException \r
- */\r
- public static DataContainer readFile(File input) throws IOException {\r
- BinaryFile rf = new BinaryFile( input, "r" );\r
- try {\r
- return readFile(rf);\r
- } finally {\r
- rf.close();\r
- } \r
- }\r
- \r
- /**\r
- * Process a data container using a format handler matching the format and version\r
- * of the file. \r
- * @param handlers Map of handlers. Keys are strings of form "format:version".\r
- */\r
- public static <T> T readFile(File input, Map<String, FormatHandler<T>> handlers) throws Exception {\r
- BinaryFile rf = new BinaryFile( input, "r" );\r
- try {\r
- return readFile(rf, handlers);\r
- } finally {\r
- rf.close();\r
- } \r
- }\r
- \r
- /**\r
- * Writes header fields of a container to the given output. Content field is\r
- * ignored.\r
- * @throws IOException \r
- */\r
- public static void writeHeader(DataOutput output, DataContainer container) throws IOException {\r
- STRING_SERIALIZER.serialize(output, container.format);\r
- INTEGER_SERIALIZER.serialize(output, container.version);\r
- METADATA_SERIALIZER.serialize(output, container.metadata);\r
- }\r
- \r
- /**\r
- * Writes a data container to the given output.\r
- * @throws IOException \r
- */\r
- public static void writeFile(DataOutput output, DataContainer container) throws IOException {\r
- writeHeader(output, container);\r
- VARIANT_SERIALIZER.serialize(output, container.content);\r
- }\r
- \r
- /**\r
- * Writes a data container to the given file\r
- * @throws IOException \r
- */\r
- public static void writeFile(File output, DataContainer container) throws IOException {\r
- BinaryFile wf = new BinaryFile( output);\r
- try {\r
- writeFile(wf, container);\r
- } finally {\r
- wf.close();\r
- } \r
- }\r
- \r
- public static byte[] writeFile(DataContainer container) throws IOException {\r
- return DATA_CONTAINER_SERIALIZER.serialize(container);\r
- }\r
-}\r
+package org.simantics.databoard.container;
+
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.impl.TreeMapBinding;
+import org.simantics.databoard.binding.mutable.Variant;
+import org.simantics.databoard.serialization.Serializer;
+import org.simantics.databoard.type.Datatype;
+import org.simantics.databoard.util.binary.BinaryFile;
+
+/**
+ * An utility class for reading files whose format follows
+ * {@link DataContainer}.
+ * @author Hannu Niemistö
+ */
+public class DataContainers {
+
+ private static final Serializer STRING_SERIALIZER =
+ Bindings.getSerializerUnchecked(Bindings.STRING);
+ private static final Serializer INTEGER_SERIALIZER =
+ Bindings.getSerializerUnchecked(Bindings.INTEGER);
+ private static final Serializer METADATA_SERIALIZER =
+ Bindings.getSerializerUnchecked(new TreeMapBinding(Bindings.STRING, Bindings.VARIANT));
+ private static final Serializer DATATYPE_SERIALIZER =
+ Bindings.getSerializerUnchecked(Datatype.class);
+ private static final Serializer VARIANT_SERIALIZER =
+ Bindings.getSerializerUnchecked(Bindings.VARIANT);
+ private static final Serializer DATA_CONTAINER_SERIALIZER =
+ Bindings.getSerializerUnchecked(DataContainer.class);
+
+ /**
+ * Binds a format name and a version together to form a format version
+ * identifier string.
+ *
+ * @param formatName
+ * @param version
+ * @return
+ */
+ public static String toFormatString(String formatName, int version) {
+ return formatName + ":" + version;
+ }
+
+ /**
+ * Reads only the header of the data container. Returns
+ * a DataContainer whose content-field is null.
+ * @throws IOException
+ */
+ public static DataContainer readHeader(DataInput input) throws IOException {
+ String format = (String)STRING_SERIALIZER.deserialize(input);
+ int version = (Integer)INTEGER_SERIALIZER.deserialize(input);
+ @SuppressWarnings("unchecked")
+ TreeMap<String,Variant> metadata = (TreeMap<String,Variant>)METADATA_SERIALIZER.deserialize(input);
+ return new DataContainer(format, version, metadata, null);
+ }
+
+ /**
+ * Consumes a header from a given stream and checks that the header satisfies the given format and version.
+ * Returns the obtained header if the check fails and null on success.
+ * @throws IOException
+ */
+ public static DataContainer requireHeader(DataInput input, String format, int version) {
+ try {
+ DataContainer header = readHeader(input);
+ if(!format.equals(header.format) || version != header.version)
+ return header;
+ else return null;
+ } catch (Throwable t) {
+ return new DataContainer("unknown", 0, null, null);
+ }
+ }
+
+ /**
+ * Consumes a header from a given stream and checks that the header satisfies the given format and version restrictions.
+ * Returns the obtained header if the check fails and null on success.
+ * @throws IOException
+ */
+ public static DataContainer requireHeader(DataInput input, String... requiredFormatStrings) {
+ try {
+ DataContainer header = readHeader(input);
+ String formatString = toFormatString(header.format, header.version);
+ for (String requiredFormatString : requiredFormatStrings) {
+ if(formatString.equals(requiredFormatString))
+ return null;
+ }
+ return header;
+ } catch (Throwable t) {
+ return new DataContainer("unknown", 0, null, null);
+ }
+ }
+
+ /**
+ * Checks that the given file satisfies the given format and version.
+ * Returns the obtained header if the check fails and null on success.
+ * @throws IOException
+ */
+ public static DataContainer validateHeader(File file, String format, int version) throws IOException {
+
+ InputStream stream = new FileInputStream( file );
+ try {
+ return DataContainers.requireHeader(new DataInputStream(stream), format, version);
+ } finally {
+ stream.close();
+ }
+
+ }
+
+ /**
+ * Checks that the given file satisfies the given format and version.
+ * Returns the obtained header if the check fails and null on success.
+ * @throws IOException
+ */
+ public static DataContainer validateHeader(File file, String... allowedFormatStrings) throws IOException {
+
+ InputStream stream = new FileInputStream( file );
+ try {
+ return DataContainers.requireHeader(new DataInputStream(stream), allowedFormatStrings);
+ } finally {
+ stream.close();
+ }
+
+ }
+
+ /**
+ * Reads only the header of the data container. Returns
+ * a DataContainer whose content-field is null.
+ * @throws IOException
+ */
+ public static DataContainer readHeader(File input) throws IOException {
+ BinaryFile rf = new BinaryFile( input, "r" );
+ try {
+ return readHeader(rf);
+ } finally {
+ rf.close();
+ }
+ }
+
+ /**
+ * Reads a data container including the content data.
+ * @throws IOException
+ */
+ public static DataContainer readFile(DataInput input) throws IOException {
+ DataContainer result = readHeader(input);
+ result.content = (Variant)VARIANT_SERIALIZER.deserialize(input);
+ return result;
+ }
+
+ /**
+ * Process a data container using a format handler matching the format and version
+ * of the file.
+ * @param handlers Map of handlers. Keys are strings of form "format:version".
+ */
+ public static <T> T readFile(DataInput input, Map<String, FormatHandler<T>> handlers) throws Exception {
+ DataContainer result = readHeader(input);
+
+ FormatHandler<T> handler = handlers.get(result.format + ":" + result.version);
+ if(handler == null)
+ throw new DataFormatException("Unknown data format " + result.format + " version " + result.version + ".");
+ Binding binding = handler.getBinding();
+
+ Datatype contentType = (Datatype)DATATYPE_SERIALIZER.deserialize(input);
+ if(!binding.type().equals(contentType))
+ throw new DataFormatException("Content type didn't match the type expected for the format " + result.format + " version " + result.version + ".");
+
+ Object value = Bindings.getSerializerUnchecked(binding).deserialize(input);
+
+ result.content = new Variant(binding, value);
+ return handler.process(result);
+ }
+
+ /**
+ * Reads a data container including the content data.
+ * @throws IOException
+ */
+ public static DataContainer readFile(File input) throws IOException {
+ BinaryFile rf = new BinaryFile( input, "r" );
+ try {
+ return readFile(rf);
+ } finally {
+ rf.close();
+ }
+ }
+
+ /**
+ * Process a data container using a format handler matching the format and version
+ * of the file.
+ * @param handlers Map of handlers. Keys are strings of form "format:version".
+ */
+ public static <T> T readFile(File input, Map<String, FormatHandler<T>> handlers) throws Exception {
+ BinaryFile rf = new BinaryFile( input, "r" );
+ try {
+ return readFile(rf, handlers);
+ } finally {
+ rf.close();
+ }
+ }
+
+ /**
+ * Writes header fields of a container to the given output. Content field is
+ * ignored.
+ * @throws IOException
+ */
+ public static void writeHeader(DataOutput output, DataContainer container) throws IOException {
+ STRING_SERIALIZER.serialize(output, container.format);
+ INTEGER_SERIALIZER.serialize(output, container.version);
+ METADATA_SERIALIZER.serialize(output, container.metadata);
+ }
+
+ /**
+ * Writes a data container to the given output.
+ * @throws IOException
+ */
+ public static void writeFile(DataOutput output, DataContainer container) throws IOException {
+ writeHeader(output, container);
+ VARIANT_SERIALIZER.serialize(output, container.content);
+ }
+
+ /**
+ * Writes a data container to the given file
+ * @throws IOException
+ */
+ public static void writeFile(File output, DataContainer container) throws IOException {
+ BinaryFile wf = new BinaryFile( output);
+ try {
+ writeFile(wf, container);
+ } finally {
+ wf.close();
+ }
+ }
+
+ public static byte[] writeFile(DataContainer container) throws IOException {
+ return DATA_CONTAINER_SERIALIZER.serialize(container);
+ }
+}