Passed
Push — master ( b3aee2...835cc2 )
by Kolja
01:09
created

jgfJsonDecorator.js ➔ fromJson   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 10
nc 1
nop 1
dl 0
loc 19
rs 9.9
c 0
b 0
f 0

1 Function

Rating   Name   Duplication   Size   Complexity  
A jgfJsonDecorator.js ➔ ... ➔ ??? 0 3 1
1
const _ = require('deepdash')(require('lodash'));
2
const check = require('check-types');
3
const { JgfNode } = require('./jgfNode');
4
const { JgfEdge } = require('./jgfEdge');
5
const { JgfGraph } = require('./jgfGraph');
6
const { JgfMultiGraph } = require('./jgfMultiGraph');
7
8
/**
9
 * Transforms graphs or multigraphs to json or vice versa.
10
 *
11
 * Note that this is just called decorator for semantic reasons and does not follow the GoF decorator design pattern.
12
 */
13
class JgfJsonDecorator {
14
15
    /**
16
     * Transforms a JGF graph or multigraph from JSON to objects.
17
     * @param {object} json
18
     */
19
    static fromJson(json) {
20
        if (!json.graph) {
21
            throw new Error('Can not handle multigraphs yet');
22
        }
23
24
        let jgraph = json.graph;
25
26
        let graph = new JgfGraph(jgraph.type, jgraph.label, jgraph.directed, jgraph.metadata);
27
28
        _.each(json.graph.nodes, (node) => {
29
            graph.addNode(new JgfNode(node.id, node.label, node.metadata));
30
        });
31
32
        _.each(json.graph.edges, (edge) => {
33
            graph.addEdge(new JgfEdge(edge.source, edge.target, edge.relation, edge.label, edge.metadata, edge.directed));
34
        });
35
36
        return graph;
37
    }
38
39
    static _guardAgainstInvalidGraphObject(graph) {
40
        if (!check.instance(graph, JgfGraph) && !check.instance(graph, JgfMultiGraph)) {
41
            throw new Error('JgfJsonDecorator can only decorate graphs or multigraphs.');
42
        }
43
    }
44
45
    /**
46
     * Transforms either a graph or a multigraph object to a JSON representation as per the spec.
47
     * @param {JgfGraph,JgfMultiGraph} graph
48
     * @returns {object}
49
     */
50
    static toJson(graph) {
51
        this._guardAgainstInvalidGraphObject(graph);
52
53
        const isSingleGraph = check.instance(graph, JgfGraph);
54
55
        let normalizedGraph = this._normalizeToMultiGraph(graph);
56
        let allGraphsJson = {
57
            graphs: [],
58
        };
59
60
        _.each(normalizedGraph.graphs, (singleGraph) => {
61
62
            let singleGraphJson = {
63
                type: singleGraph.type,
64
                label: singleGraph.label,
65
                directed: singleGraph.directed,
66
                metadata: singleGraph.metadata,
67
                nodes: [],
68
                edges: [],
69
            };
70
71
            this._nodesToJson(singleGraph, singleGraphJson);
72
            this._edgesToJson(singleGraph, singleGraphJson);
73
74
            allGraphsJson.graphs.push(singleGraphJson);
75
        });
76
77
        if (isSingleGraph) {
78
            return this._removeNullValues({ graph: allGraphsJson.graphs[0] });
79
        }
80
81
        return this._removeNullValues(allGraphsJson);
82
    }
83
84
    static _removeNullValues(json) {
85
        return _.filterDeep(json, (value) => value !== null);
86
    }
87
88
    /**
89
     * @param {JgfGraph} graph
90
     * @param {object} json
91
     */
92
    static _edgesToJson(graph, json) {
93
        _.each(graph.edges, (edge) => {
94
            json.edges.push({
95
                source: edge.source,
96
                target: edge.target,
97
                relation: edge.relation,
98
                label: edge.label,
99
                metadata: edge.metadata,
100
                directed: edge.directed,
101
            });
102
        });
103
    }
104
105
    /**
106
     * @param {JgfGraph} graph
107
     * @param {object} json
108
     */
109
    static _nodesToJson(graph, json) {
110
        _.each(graph.nodes, (node) => {
111
            json.nodes.push({
112
                id: node.id,
113
                label: node.label,
114
                metadata: node.metadata,
115
            });
116
        });
117
    }
118
119
    static _normalizeToMultiGraph(graph) {
120
        let normalizedGraph = graph;
121
        if (check.instance(graph, JgfGraph)) {
122
            normalizedGraph = new JgfMultiGraph();
123
            normalizedGraph.addGraph(graph);
124
        }
125
126
        return normalizedGraph;
127
    }
128
}
129
130
module.exports = {
131
    JgfJsonDecorator,
132
};