Skip to contentMethod: getTreeRoot()
1: /**
2: * Copyright (C) 2020 Czech Technical University in Prague
3: * <p>
4: * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
5: * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
6: * version.
7: * <p>
8: * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9: * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10: * details. You should have received a copy of the GNU General Public License along with this program. If not, see
11: * <http://www.gnu.org/licenses/>.
12: */
13: package cz.cvut.kbss.jsonld.serialization;
14:
15: import cz.cvut.kbss.jsonld.JsonLd;
16: import cz.cvut.kbss.jsonld.common.BeanAnnotationProcessor;
17: import cz.cvut.kbss.jsonld.serialization.model.CollectionNode;
18: import cz.cvut.kbss.jsonld.serialization.model.CompositeNode;
19: import cz.cvut.kbss.jsonld.serialization.model.JsonNode;
20: import cz.cvut.kbss.jsonld.serialization.traversal.InstanceVisitor;
21: import cz.cvut.kbss.jsonld.serialization.traversal.SerializationContext;
22:
23: import java.util.Collection;
24: import java.util.List;
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 ValueSerializer literalSerializer;
37: private final ValueSerializer annotationSerializer;
38:
39: public JsonLdTreeBuilder() {
40: final MultilingualStringSerializer msSerializer = new MultilingualStringSerializer();
41: this.literalSerializer = new LiteralValueSerializer(msSerializer);
42: this.annotationSerializer = new AnnotationValueSerializer(msSerializer);
43: }
44:
45: @Override
46: public void openObject(SerializationContext<?> ctx) {
47: final CompositeNode newCurrent =
48: ctx.getAttributeId() != null ? JsonNodeFactory.createObjectNode(ctx.getAttributeId()) :
49: JsonNodeFactory.createObjectNode();
50: openNewNode(newCurrent);
51: }
52:
53: private void openNewNode(CompositeNode newNode) {
54: if (currentNode != null) {
55: if (currentNode.isOpen()) {
56: nodeStack.push(currentNode);
57: }
58: currentNode.addItem(newNode);
59: }
60: this.currentNode = newNode;
61: }
62:
63: @Override
64: public void closeObject(SerializationContext<?> ctx) {
65: currentNode.close();
66: if (!nodeStack.empty()) {
67: this.currentNode = nodeStack.pop();
68: }
69: }
70:
71: @Override
72: public void visitIdentifier(SerializationContext<String> idCtx) {
73: assert currentNode.isOpen();
74: currentNode.addItem(JsonNodeFactory.createObjectIdNode(JsonLd.ID, idCtx.getValue()));
75: }
76:
77: @Override
78: public void visitTypes(SerializationContext<Collection<String>> typesCtx) {
79: final CollectionNode typesNode = JsonNodeFactory.createCollectionNode(JsonLd.TYPE, typesCtx.getValue());
80: typesCtx.getValue().forEach(type -> typesNode.addItem(JsonNodeFactory.createLiteralNode(type)));
81: currentNode.addItem(typesNode);
82: }
83:
84: @Override
85: public void visitAttribute(SerializationContext<?> ctx) {
86: if (ctx.getValue() != null && !BeanAnnotationProcessor.isObjectProperty(ctx.getField())) {
87: assert currentNode != null;
88: final List<JsonNode> nodes;
89: if (BeanAnnotationProcessor.isAnnotationProperty(ctx.getField())) {
90: nodes = annotationSerializer.serialize(ctx.getAttributeId(), ctx.getValue());
91: } else {
92: nodes = literalSerializer.serialize(ctx.getAttributeId(), ctx.getValue());
93: }
94: nodes.forEach(node -> currentNode.addItem(node));
95: }
96: }
97:
98: @Override
99: public void openCollection(SerializationContext<? extends Collection<?>> ctx) {
100: final CollectionNode newCurrent =
101: ctx.getAttributeId() != null ? JsonNodeFactory.createCollectionNode(ctx.getAttributeId(),
102: ctx.getValue()) :
103: JsonNodeFactory.createCollectionNode(ctx.getValue());
104: openNewNode(newCurrent);
105: }
106:
107: @Override
108: public void closeCollection(SerializationContext<?> ctx) {
109: assert currentNode instanceof CollectionNode;
110: closeObject(ctx);
111: }
112:
113: public CompositeNode getTreeRoot() {
114: return currentNode;
115: }
116: }