-package org.simantics.db.common;\r
-\r
-import java.io.IOException;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.serialization.SerializationException;\r
-import org.simantics.databoard.serialization.Serializer;\r
-import org.simantics.db.Metadata;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.exception.DatabaseException;\r
-\r
-public class CommandMetadata implements Metadata {\r
-\r
- public static final boolean DEBUG = false;\r
- public static final String RESET_COMMAND = "// RESET";\r
- \r
- private static final Binding BINDING = \r
- Bindings.getBindingUnchecked(CommandMetadata.class);\r
- private static final Serializer SERIALIZER = \r
- Bindings.getSerializerUnchecked(BINDING);\r
- \r
- public List<Command> commands;\r
- \r
- public static class Command {\r
- public long modelId;\r
- public String command;\r
- \r
- public Command() { \r
- }\r
- \r
- public Command(long modelId, String command) {\r
- super();\r
- this.modelId = modelId;\r
- this.command = command;\r
- }\r
- }\r
- \r
- public CommandMetadata() {\r
- }\r
-\r
- @Override\r
- public byte[] serialise(Session session) {\r
- try {\r
- return SERIALIZER.serialize(this);\r
- } catch (IOException e) {\r
- e.printStackTrace();\r
- throw new RuntimeException(e);\r
- }\r
- }\r
- \r
- public static CommandMetadata deserialise(Session session, byte[] input) {\r
- if(input == null) {\r
- CommandMetadata metadata = new CommandMetadata();\r
- metadata.commands = new ArrayList<Command>();\r
- return metadata;\r
- }\r
- try {\r
- return (CommandMetadata)SERIALIZER.deserialize(input);\r
- } catch (SerializationException e) {\r
- e.printStackTrace();\r
- } catch (IOException e) {\r
- e.printStackTrace();\r
- }\r
- return null;\r
- }\r
-\r
- public CommandMetadata add(Command command) {\r
- commands.add(command);\r
- return this;\r
- }\r
- \r
- public List<Command> getCommands() {\r
- return commands;\r
- }\r
-\r
- public static void add(WriteGraph graph, long modelId, String command) throws DatabaseException {\r
- if(DEBUG) {\r
- System.out.println("-------------------------------------------------------------");\r
- System.out.println(command);\r
- }\r
- graph.addMetadata(graph.getMetadata(CommandMetadata.class).add(\r
- new Command(modelId, command)));\r
- }\r
- \r
- public static void addReset(WriteGraph graph, long modelId) throws DatabaseException {\r
- graph.addMetadata(graph.getMetadata(CommandMetadata.class).add(\r
- new Command(modelId, RESET_COMMAND)));\r
- }\r
-}\r
+package org.simantics.db.common;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.serialization.Serializer;
+import org.simantics.db.Metadata;
+import org.simantics.db.Session;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.service.Bytes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import gnu.trove.list.array.TByteArrayList;
+
+public final class CommandMetadata implements Metadata {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CommandMetadata.class);
+
+ public static final boolean DEBUG = false;
+ public static final String RESET_COMMAND = "// RESET";
+
+ private static final Binding BINDING =
+ Bindings.getBindingUnchecked(CommandMetadata.class);
+ private static final Serializer SERIALIZER =
+ Bindings.getSerializerUnchecked(BINDING);
+
+ public List<Command> commands;
+
+ public static final class Command {
+ public long modelId;
+ public String command;
+
+ public Command() {
+ }
+
+ public Command(long modelId, String command) {
+ super();
+ this.modelId = modelId;
+ this.command = command;
+ }
+ }
+
+ public CommandMetadata() {
+ }
+
+ @Override
+ public byte[] serialise(Session session) {
+ try {
+ TByteArrayList commandsSerialized = new TByteArrayList(4096);
+ byte[] bytes = new byte[8];
+
+ int commandsSize = commands.size();
+ Bytes.writeLE(bytes, 0, commandsSize);
+ commandsSerialized.add(bytes, 0, 4);
+
+ for (Command command : commands) {
+ Bytes.writeLE8(bytes, 0, command.modelId);
+ commandsSerialized.add(bytes);
+ byte[] commandBytes = command.command.getBytes(StandardCharsets.UTF_8);
+ Bytes.writeLE(bytes, 0, commandBytes.length);
+ commandsSerialized.add(bytes, 0, 4);
+ commandsSerialized.add(commandBytes);
+ }
+ return commandsSerialized.toArray();
+ } catch (Exception ee) {
+ // Ok, backwards compatibility required
+ // This is rather slow operation hence the new implementation above
+ try {
+ return SERIALIZER.serialize(this);
+ } catch (IOException e) {
+ LOGGER.error("Could not serialize", e);
+ LOGGER.error("Original exception for new serialisation", ee);
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public static CommandMetadata deserialise(Session session, byte[] input) {
+ if(input == null) {
+ CommandMetadata metadata = new CommandMetadata();
+ metadata.commands = new ArrayList<Command>();
+ return metadata;
+ }
+ try {
+ int byteIndex = 0;
+ int commandsSize = Bytes.readLE4(input, byteIndex);
+ byteIndex += 4;
+
+ List<Command> commands = new ArrayList<>(commandsSize);
+ for (int i = 0; i < commandsSize; i++) {
+ long modelId = Bytes.readLE8(input, byteIndex);
+ byteIndex += 8;
+ int commandsLength = Bytes.readLE4(input, byteIndex);
+ byteIndex += 4;
+
+ String command = new String(input, byteIndex, commandsLength);
+ byteIndex += commandsLength;
+ Command comm = new Command(modelId, command);
+ commands.add(comm);
+ }
+ CommandMetadata metadata = new CommandMetadata();
+ metadata.commands = commands;
+ return metadata;
+ } catch (Exception ee) {
+ // Ok, backwards compatibility required
+ // This is rather slow operation hence the new implementation above
+ try {
+ return (CommandMetadata)SERIALIZER.deserialize(input);
+ } catch (Exception e) {
+ LOGGER.error("Could not deserialise", e);
+ LOGGER.error("Original exception for new deserialisation", ee);
+ }
+ return null;
+ }
+ }
+
+ public CommandMetadata add(Command command) {
+ commands.add(command);
+ return this;
+ }
+
+ public List<Command> getCommands() {
+ return commands;
+ }
+
+ public static void add(WriteGraph graph, long modelId, String command) throws DatabaseException {
+ if(DEBUG) {
+ System.out.println("-------------------------------------------------------------");
+ System.out.println(command);
+ }
+ graph.addMetadata(graph.getMetadata(CommandMetadata.class).add(
+ new Command(modelId, command)));
+ }
+
+ public static void addReset(WriteGraph graph, long modelId) throws DatabaseException {
+ graph.addMetadata(graph.getMetadata(CommandMetadata.class).add(
+ new Command(modelId, RESET_COMMAND)));
+ }
+}