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