com.tinkerpop.rexster.protocol.serializer.msgpack.templates.ResultsConverter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rexster-protocol Show documentation
Show all versions of rexster-protocol Show documentation
RexPro is a binary protocol for Rexster graph server.
package com.tinkerpop.rexster.protocol.serializer.msgpack.templates;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.pipes.util.structures.Row;
import com.tinkerpop.pipes.util.structures.Table;
import com.tinkerpop.rexster.Tokens;
import org.msgpack.packer.Packer;
import org.msgpack.type.ArrayValue;
import org.msgpack.type.MapValue;
import org.msgpack.type.NilValue;
import org.msgpack.type.Value;
import org.msgpack.type.ValueFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Universally useful msgpack object serialization and deserialization functions
*
* @author Blake Eggleston (bdeggleston.github.com)
*/
public class ResultsConverter {
static Object serializeElementId(final Element element) {
final Object id = element.getId();
if (id.getClass().isPrimitive()) {
return id;
} else {
return id.toString();
}
}
static public void serializeObject(final Object object, final Packer packer) throws Exception {
if (object == null) {
packer.write(ValueFactory.createNilValue());
} else if (object instanceof String || object instanceof Number || object instanceof Boolean) {
packer.write(object);
} else if (object instanceof Element) {
try {
final Element element = (Element) object;
final Set propertyKeys = element.getPropertyKeys();
final int propertySize = propertyKeys.size();
final boolean isVertex = !(element instanceof Edge);
final int elementSize = (isVertex ? 2 : 5) + ((propertySize > 0) ? 1 : 0);
packer.writeMapBegin(elementSize);
packer.write(Tokens._ID);
packer.write(serializeElementId(element));
if (isVertex) {
packer.write(Tokens._TYPE);
packer.write(Tokens.VERTEX);
} else {
final Edge edge = (Edge) element;
packer.write(Tokens._TYPE);
packer.write(Tokens.EDGE);
packer.write(Tokens._IN_V);
packer.write(serializeElementId(edge.getVertex(Direction.IN)));
packer.write(Tokens._OUT_V);
packer.write(serializeElementId(edge.getVertex(Direction.OUT)));
packer.write(Tokens._LABEL);
packer.write(edge.getLabel());
}
if (propertyKeys.size() > 0) {
packer.write(Tokens._PROPERTIES);
packer.writeMapBegin(propertySize);
final Iterator itty = propertyKeys.iterator();
while (itty.hasNext()) {
final String propertyKey = itty.next();
packer.write(propertyKey);
serializeObject(element.getProperty(propertyKey), packer);
}
packer.writeMapEnd(false);
}
packer.writeMapEnd(false);
} catch (Exception e) {
// if a transaction gets closed and the element goes out of scope it may not serialize. in these
// cases the vertex will just be written as null. this can happen during binding serialization.
// specific case is doing this:
// v = g.addVertex()
// g.rollback()
// in some graphs v will go out of scope, yet it is still on the bindings as a Vertex object.
packer.writeNil();
}
} else if (object instanceof Map) {
final Map map = (Map) object;
packer.writeMapBegin(map.size());
for (Object key : map.keySet()) {
if(key instanceof Element) {
// restructure element -> x maps
// this is typical in Tree and Map returns where the key is an object value instead of a
// primitive. MsgPack can't process keys that way so the data needs to be restructured
// so that it doesn't end up simply being toString'd
final Element element = (Element) key;
writeMapKey(element.getId(), packer);
final HashMap m = new HashMap();
m.put(Tokens._KEY, element);
m.put(Tokens._VALUE, map.get(key));
serializeObject(m, packer);
} else {
writeMapKey(key, packer);
serializeObject(map.get(key), packer);
}
}
packer.writeMapEnd();
} else if (object instanceof Table) {
final Table table = (Table) object;
final Iterator rows = table.iterator();
packer.writeArrayBegin(table.size());
while (rows.hasNext()) {
serializeObject(rows.next(), packer);
}
packer.writeArrayEnd();
} else if (object instanceof Row) {
final Row row = (Row) object;
final List columnNames = row.getColumnNames();
packer.writeMapBegin(columnNames.size());
for (String columnName : columnNames) {
packer.write(columnName);
serializeObject(row.getColumn(columnName), packer);
}
packer.writeMapEnd(false);
} else if (object instanceof Iterable) {
Collection contents;
if (object instanceof Collection) {
contents = (Collection) object;
} else {
contents = iterateToList(((Iterable) object).iterator());
}
packer.writeArrayBegin(contents.size());
for (Object o : contents) {
serializeObject(o, packer);
}
packer.writeArrayEnd();
} else if (object instanceof Iterator) {
//we need to know the array size before beginning serialization
final Collection contents = iterateToList((Iterator) object);
packer.writeArrayBegin(contents.size());
for (Object o : contents) {
serializeObject(o, packer);
}
packer.writeArrayEnd();
} else if (object instanceof NilValue) {
packer.write((NilValue) object);
} else {
packer.write(object.toString());
}
}
private static void writeMapKey(final Object key, final Packer packer) throws IOException {
// map keys must be something serializable by MsgPack. don't get too fancy
if (key instanceof String || key instanceof Number) {
packer.write(key);
} else {
packer.write(key.toString());
}
}
private static ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy