jgfJsonDecorator.js   A
last analyzed

Complexity

Total Complexity 21
Complexity/F 1.31

Size

Lines of Code 164
Function Count 16

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 21
eloc 77
mnd 5
bc 5
fnc 16
dl 0
loc 164
rs 10
bpm 0.3125
cpm 1.3125
noi 0
c 0
b 0
f 0

9 Functions

Rating   Name   Duplication   Size   Complexity  
A JgfJsonDecorator.fromJson 0 16 4
A JgfJsonDecorator._removeNullValues 0 3 2
A JgfJsonDecorator._guardAgainstInvalidGraphObject 0 5 2
A JgfJsonDecorator._transformGraphsToJson 0 19 2
A JgfJsonDecorator._nodesToJson 0 9 2
A JgfJsonDecorator._normalizeToMultiGraph 0 9 2
A JgfJsonDecorator._graphFromJson 0 13 3
A JgfJsonDecorator._edgesToJson 0 12 2
A JgfJsonDecorator.toJson 0 21 2
1
const _ = require('lodash');
2
require('deepdash')(_);
3
const check = require('check-types');
4
const { JgfNode } = require('./jgfNode');
5
const { JgfEdge } = require('./jgfEdge');
6
const { JgfGraph } = require('./jgfGraph');
7
const { JgfMultiGraph } = require('./jgfMultiGraph');
8
9
/**
10
 * Transforms graphs or multi graphs to json or vice versa.
11
 *
12
 * Note that this is just called decorator for semantic reasons and does not follow and does not intend to follow
13
 * the GoF decorator design pattern.
14
 */
15
class JgfJsonDecorator {
16
17
    /**
18
     * Creates a Jgf graph or multi graph from JSON.
19
     * @param {object} json JSON to be transformed to a graph or multigraph. This has to be according to the JGF.
20
     * @throws Error if json can not be transformed to a graph or multi graph.
21
     * @returns {JgfGraph|JgfMultiGraph} The created Jgf graph or multi graph object.
22
     */
23
    static fromJson(json) {
24
        if (check.assigned(json.graph)) {
25
            return this._graphFromJson(json.graph);
26
        }
27
28
        if (check.assigned(json.graphs)) {
29
            let graph = new JgfMultiGraph(json.type, json.label, json.metadata);
30
            _.each(json.graphs, (graphJson) => {
31
                graph.addGraph(this._graphFromJson(graphJson))
32
            });
33
34
            return graph;
35
        }
36
37
        throw new Error('Passed json has to to have a "graph" or "graphs" property.');
38
    }
39
40
    /**
41
     * Creates a single JGF graph from JSON.
42
     * @param {object} graphJson
43
     * @returns {JgfGraph}
44
     * @private
45
     */
46
    static _graphFromJson(graphJson) {
47
        let graph = new JgfGraph(graphJson.type, graphJson.label, graphJson.directed, graphJson.metadata);
48
49
        _.each(graphJson.nodes, (node) => {
50
            graph.addNode(new JgfNode(node.id, node.label, node.metadata));
51
        });
52
53
        _.each(graphJson.edges, (edge) => {
54
            graph.addEdge(new JgfEdge(edge.source, edge.target, edge.relation, edge.label, edge.metadata, edge.directed));
55
        });
56
57
        return graph;
58
    }
59
60
    static _guardAgainstInvalidGraphObject(graph) {
61
        if (!check.instance(graph, JgfGraph) && !check.instance(graph, JgfMultiGraph)) {
62
            throw new Error('JgfJsonDecorator can only decorate graphs or multi graphs.');
63
        }
64
    }
65
66
    /**
67
     * Transforms either a graph or a multi graph object to a JSON representation as per the spec.
68
     * @param {JgfGraph|JgfMultiGraph} graph The graph to be transformed to JSON.
69
     * @throws Error if the passed graph or multi graph can not be transformed to JSON.
70
     * @returns {object} A JSON representation of the passed graph or multi graph as according to the JGF.
71
     */
72
    static toJson(graph) {
73
        this._guardAgainstInvalidGraphObject(graph);
74
75
        const isSingleGraph = check.instance(graph, JgfGraph);
76
77
        let allGraphsJson = {
78
            graphs: [],
79
        };
80
81
        this._transformGraphsToJson(graph, allGraphsJson);
82
83
        if (isSingleGraph) {
84
            return this._removeNullValues({ graph: allGraphsJson.graphs[0] });
85
        }
86
87
        allGraphsJson.type = graph.type;
88
        allGraphsJson.label = graph.label;
89
        allGraphsJson.metadata = graph.metadata;
90
91
        return this._removeNullValues(allGraphsJson);
92
    }
93
94
    static _transformGraphsToJson(graph, allGraphsJson) {
95
        let normalizedGraph = this._normalizeToMultiGraph(graph);
96
        _.each(normalizedGraph.graphs, (singleGraph) => {
97
98
            let singleGraphJson = {
99
                type: singleGraph.type,
100
                label: singleGraph.label,
101
                directed: singleGraph.directed,
102
                metadata: singleGraph.metadata,
103
                nodes: [],
104
                edges: [],
105
            };
106
107
            this._nodesToJson(singleGraph, singleGraphJson);
108
            this._edgesToJson(singleGraph, singleGraphJson);
109
110
            allGraphsJson.graphs.push(singleGraphJson);
111
        });
112
    }
113
114
    static _removeNullValues(json) {
115
        return _.filterDeep(json, (value) => value !== null);
116
    }
117
118
    /**
119
     * @param {JgfGraph} graph
120
     * @param {object} json
121
     * @private
122
     */
123
    static _edgesToJson(graph, json) {
124
        _.each(graph.edges, (edge) => {
125
            json.edges.push({
126
                source: edge.source,
127
                target: edge.target,
128
                relation: edge.relation,
129
                label: edge.label,
130
                metadata: edge.metadata,
131
                directed: edge.directed,
132
            });
133
        });
134
    }
135
136
    /**
137
     * @param {JgfGraph} graph
138
     * @param {object} json
139
     * @private
140
     */
141
    static _nodesToJson(graph, json) {
142
        _.each(graph.nodes, (node) => {
143
            json.nodes.push({
144
                id: node.id,
145
                label: node.label,
146
                metadata: node.metadata,
147
            });
148
        });
149
    }
150
151
    static _normalizeToMultiGraph(graph) {
152
        let normalizedGraph = graph;
153
        if (check.instance(graph, JgfGraph)) {
154
            normalizedGraph = new JgfMultiGraph();
155
            normalizedGraph.addGraph(graph);
156
        }
157
158
        return normalizedGraph;
159
    }
160
}
161
162
module.exports = {
163
    JgfJsonDecorator,
164
};
165