blob: 9b6bd437a3bd27cc3f93c701e3f835ad08d1c8ce [file]
/*
* Copyright DataStax, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
const types = require('../../types');
const utils = require('../../utils');
const Point = require('../../geometry/point');
const Polygon = require('../../geometry/polygon');
const LineString = require('../../geometry/line-string');
const graphModule = require('./');
const Edge = graphModule.Edge;
const Path = graphModule.Path;
const Property = graphModule.Property;
const Vertex = graphModule.Vertex;
const VertexProperty = graphModule.VertexProperty;
const graphSONTypeKey = '@type';
const graphSONValueKey = '@value';
/**
* GraphSON2 Reader
* @ignore
* @internal
* @constructor
*/
class GraphSONReader {
constructor() {
const deserializerConstructors = [
VertexDeserializer,
EdgeDeserializer,
VertexPropertyDeserializer,
PropertyDeserializer,
PathDeserializer,
UuidDeserializer,
InstantDeserializer,
LongDeserializer,
BigDecimalDeserializer,
BigIntegerDeserializer,
InetAddressDeserializer,
LocalDateDeserializer,
LocalTimeDeserializer,
BlobDeserializer,
PointDeserializer,
LineStringDeserializer,
PolygonDeserializer
];
this._deserializers = {};
deserializerConstructors.forEach(function (C) {
const s = new C();
s.reader = this;
this._deserializers[s.key] = s;
}, this);
}
read(obj) {
if (obj === undefined) {
return undefined;
}
if (Array.isArray(obj)) {
return obj.map(item => this.read(item));
}
const type = obj[graphSONTypeKey];
if (type) {
const d = this._deserializers[type];
if (d) {
// Use type serializer
return d.deserialize(obj);
}
return obj[graphSONValueKey];
}
if (obj && typeof obj === 'object' && obj.constructor === Object) {
return this._deserializeObject(obj);
}
// Default (for boolean, number and other scalars)
return obj;
}
_deserializeObject(obj) {
const keys = Object.keys(obj);
const result = {};
for (let i = 0; i < keys.length; i++) {
result[keys[i]] = this.read(obj[keys[i]]);
}
return result;
}
}
class VertexDeserializer {
constructor() {
this.key = 'g:Vertex';
}
deserialize(obj) {
const value = obj[graphSONValueKey];
return new Vertex(this.reader.read(value['id']), value['label'], this.reader.read(value['properties']));
}
}
class VertexPropertyDeserializer {
constructor() {
this.key = 'g:VertexProperty';
}
deserialize(obj) {
const value = obj[graphSONValueKey];
return new VertexProperty(this.reader.read(value['id']), value['label'], this.reader.read(value['value']), this.reader.read(value['properties']));
}
}
class PropertyDeserializer {
constructor() {
this.key = 'g:Property';
}
deserialize(obj) {
const value = obj[graphSONValueKey];
return new Property(value['key'], this.reader.read(value['value']));
}
}
class EdgeDeserializer {
constructor() {
this.key = 'g:Edge';
}
deserialize(obj) {
const value = obj[graphSONValueKey];
return new Edge(this.reader.read(value['id']), this.reader.read(value['outV']), value['outVLabel'], value['label'], this.reader.read(value['inV']), value['inVLabel'], this.reader.read(value['properties']));
}
}
class PathDeserializer {
constructor() {
this.key = 'g:Path';
}
deserialize(obj) {
const value = obj[graphSONValueKey];
const objects = value['objects'].map(function objectMapItem(o) {
return this.reader.read(o);
}, this);
return new Path(this.reader.read(value['labels']), objects);
}
}
/**
* Uses toString() instance method and fromString() static method to serialize and deserialize the value.
* @abstract
* @private
*/
class StringBasedDeserializer {
/**
* Creates a new instance of the deserializer.
* @param {String} key
* @param {Function} targetType
*/
constructor(key, targetType) {
if (!key) {
throw new Error('Deserializer must provide a type key');
}
if (!targetType) {
throw new Error('Deserializer must provide a target type');
}
this.key = key;
this.targetType = targetType;
}
deserialize(obj) {
let value = obj[graphSONValueKey];
if (typeof value !== 'string') {
value = value.toString();
}
return this.targetType.fromString(value);
}
}
class UuidDeserializer extends StringBasedDeserializer {
constructor() {
super('g:UUID', types.Uuid);
}
}
class LongDeserializer extends StringBasedDeserializer {
constructor() {
super('g:Int64', types.Long);
}
}
class BigDecimalDeserializer extends StringBasedDeserializer {
constructor() {
super('gx:BigDecimal', types.BigDecimal);
}
}
class BigIntegerDeserializer extends StringBasedDeserializer {
constructor() {
super('gx:BigInteger', types.Integer);
}
}
class InetAddressDeserializer extends StringBasedDeserializer {
constructor() {
super('gx:InetAddress', types.InetAddress);
}
}
class LocalDateDeserializer extends StringBasedDeserializer {
constructor() {
super('gx:LocalDate', types.LocalDate);
}
}
class LocalTimeDeserializer extends StringBasedDeserializer {
constructor() {
super('gx:LocalTime', types.LocalTime);
}
}
class InstantDeserializer extends StringBasedDeserializer {
constructor() {
super('gx:Instant', Date);
}
deserialize(obj) {
return new Date(obj[graphSONValueKey]);
}
}
class BlobDeserializer extends StringBasedDeserializer {
constructor() {
super('dse:Blob', Buffer);
}
deserialize(obj) {
return utils.allocBufferFromString(obj[graphSONValueKey], 'base64');
}
}
class PointDeserializer extends StringBasedDeserializer {
constructor() {
super('dse:Point', Point);
}
}
class LineStringDeserializer extends StringBasedDeserializer {
constructor() {
super('dse:LineString', LineString);
}
}
class PolygonDeserializer extends StringBasedDeserializer {
constructor() {
super('dse:Polygon', Polygon);
}
}
module.exports = GraphSONReader;