| /* |
| * 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; |