Skip to contentMethod: static {...}
1: /**
2: * Copyright (C) 2022 Czech Technical University in Prague
3: *
4: * This program is free software: you can redistribute it and/or modify it under
5: * the terms of the GNU General Public License as published by the Free Software
6: * Foundation, either version 3 of the License, or (at your option) any
7: * later version.
8: *
9: * This program is distributed in the hope that it will be useful, but WITHOUT
10: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12: * details. You should have received a copy of the GNU General Public License
13: * along with this program. If not, see <http://www.gnu.org/licenses/>.
14: */
15: package cz.cvut.kbss.jsonld.serialization;
16:
17: import cz.cvut.kbss.jsonld.JsonLd;
18: import cz.cvut.kbss.jsonld.serialization.model.CollectionNode;
19: import cz.cvut.kbss.jsonld.serialization.model.CompositeNode;
20: import cz.cvut.kbss.jsonld.serialization.model.JsonNode;
21: import cz.cvut.kbss.jsonld.serialization.traversal.InstanceVisitor;
22: import cz.cvut.kbss.jsonld.serialization.traversal.SerializationContext;
23:
24: import java.util.Collection;
25: import java.util.Stack;
26:
27: /**
28: * Builds an abstract representation of a JSON-LD tree, which is a result of object graph traversal by {@link
29: * cz.cvut.kbss.jsonld.serialization.traversal.ObjectGraphTraverser}.
30: */
31: public class JsonLdTreeBuilder implements InstanceVisitor {
32:
33: private final Stack<CompositeNode> nodeStack = new Stack<>();
34: private CompositeNode currentNode;
35:
36: private final ValueSerializers serializers;
37:
38: public JsonLdTreeBuilder(ValueSerializers serializers) {
39: this.serializers = serializers;
40: }
41:
42: @Override
43: public boolean visitObject(SerializationContext<?> ctx) {
44: if (serializers.hasCustomSerializer(ctx.getValue().getClass())) {
45: final ValueSerializer serializer = serializers.getSerializer(ctx).get();
46: final JsonNode node = serializer.serialize(ctx.getValue(), ctx);
47: if (node != null) {
48: if (currentNode != null) {
49: currentNode.addItem(node);
50: } else {
51: assert node instanceof CompositeNode;
52: currentNode = (CompositeNode) node;
53: }
54: }
55: return false;
56: }
57: return true;
58: }
59:
60: @Override
61: public void openObject(SerializationContext<?> ctx) {
62: final CompositeNode newCurrent =
63: ctx.getAttributeId() != null ? JsonNodeFactory.createObjectNode(ctx.getAttributeId()) :
64: JsonNodeFactory.createObjectNode();
65: openNewNode(newCurrent);
66: }
67:
68: private void openNewNode(CompositeNode newNode) {
69: if (currentNode != null) {
70: if (currentNode.isOpen()) {
71: nodeStack.push(currentNode);
72: }
73: currentNode.addItem(newNode);
74: }
75: this.currentNode = newNode;
76: }
77:
78: @Override
79: public void closeObject(SerializationContext<?> ctx) {
80: currentNode.close();
81: if (!nodeStack.empty()) {
82: this.currentNode = nodeStack.pop();
83: }
84: }
85:
86: @Override
87: public void visitIdentifier(SerializationContext<String> idCtx) {
88: assert currentNode.isOpen();
89: currentNode.addItem(JsonNodeFactory.createObjectIdNode(JsonLd.ID, idCtx.getValue()));
90: }
91:
92: @Override
93: public void visitTypes(SerializationContext<Collection<String>> typesCtx) {
94: final CollectionNode typesNode = JsonNodeFactory.createCollectionNode(JsonLd.TYPE, typesCtx.getValue());
95: typesCtx.getValue().forEach(type -> typesNode.addItem(JsonNodeFactory.createLiteralNode(type)));
96: currentNode.addItem(typesNode);
97: }
98:
99: @Override
100: public void visitAttribute(SerializationContext<?> ctx) {
101: if (ctx.getValue() != null) {
102: assert currentNode != null;
103: final ValueSerializer serializer = serializers.getOrDefault(ctx);
104: final JsonNode node = serializer.serialize(ctx.getValue(), ctx);
105: if (node != null) {
106: currentNode.addItem(node);
107: }
108: }
109: }
110:
111: @Override
112: public void openCollection(SerializationContext<? extends Collection<?>> ctx) {
113: final CollectionNode newCurrent =
114: ctx.getAttributeId() != null ? JsonNodeFactory.createCollectionNode(ctx.getAttributeId(),
115: ctx.getValue()) :
116: JsonNodeFactory.createCollectionNode(ctx.getValue());
117: openNewNode(newCurrent);
118: }
119:
120: @Override
121: public void closeCollection(SerializationContext<?> ctx) {
122: assert currentNode instanceof CollectionNode;
123: closeObject(ctx);
124: }
125:
126: public CompositeNode getTreeRoot() {
127: return currentNode;
128: }
129: }