Skip to content

Package: DefaultInstanceBuilder

DefaultInstanceBuilder

nameinstructionbranchcomplexitylinemethod
DefaultInstanceBuilder(TargetClassResolver)
M: 0 C: 16
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
addNodeReference(String)
M: 0 C: 18
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
addNodeReference(String, String)
M: 4 C: 28
88%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 7
100%
M: 0 C: 1
100%
addValue(Object)
M: 4 C: 9
69%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 0 C: 3
100%
M: 0 C: 1
100%
addValue(String, Object)
M: 8 C: 39
83%
M: 2 C: 6
75%
M: 2 C: 3
60%
M: 0 C: 12
100%
M: 0 C: 1
100%
buildPropertiesContext(String)
M: 0 C: 32
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
closeCollection()
M: 0 C: 11
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
closeObject()
M: 0 C: 14
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
getCurrentCollectionElementType()
M: 7 C: 4
36%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 2 C: 1
33%
M: 0 C: 1
100%
getCurrentContextType()
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getCurrentRoot()
M: 0 C: 9
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getKnownInstance(String)
M: 0 C: 24
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
isPlural(String)
M: 4 C: 19
83%
M: 1 C: 5
83%
M: 1 C: 3
75%
M: 0 C: 3
100%
M: 0 C: 1
100%
isPropertyMapped(String)
M: 0 C: 13
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
openCollection(CollectionType)
M: 0 C: 15
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
openCollection(String)
M: 0 C: 78
100%
M: 0 C: 8
100%
M: 0 C: 5
100%
M: 0 C: 16
100%
M: 0 C: 1
100%
openObject(Class)
M: 4 C: 42
91%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 11
100%
M: 0 C: 1
100%
openObject(String, List)
M: 8 C: 64
89%
M: 2 C: 4
67%
M: 2 C: 2
50%
M: 0 C: 15
100%
M: 0 C: 1
100%
replaceCurrentContext(Object, InstanceContext)
M: 0 C: 17
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
static {...}
M: 0 C: 1
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
verifyPluralAttribute(String, Field)
M: 0 C: 9
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%

Coverage

1: /**
2: * Copyright (C) 2017 Czech Technical University in Prague
3: * <p>
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: * <p>
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.deserialization;
16:
17: import cz.cvut.kbss.jsonld.JsonLd;
18: import cz.cvut.kbss.jsonld.common.BeanAnnotationProcessor;
19: import cz.cvut.kbss.jsonld.common.BeanClassProcessor;
20: import cz.cvut.kbss.jsonld.common.CollectionType;
21: import cz.cvut.kbss.jsonld.deserialization.util.TargetClassResolver;
22: import cz.cvut.kbss.jsonld.exception.JsonLdDeserializationException;
23:
24: import java.lang.reflect.Field;
25: import java.util.*;
26:
27: /**
28: * Default implementation of the JSON-LD deserializer, which takes values parsed from a JSON-LD document and builds Java
29: * instances from them.
30: */
31: public class DefaultInstanceBuilder implements InstanceBuilder {
32:
33: // Identifiers to instances
34: private final Map<String, Object> knownInstances = new HashMap<>();
35: private final Stack<InstanceContext> openInstances = new Stack<>();
36:
37: private final TargetClassResolver classResolver;
38:
39: private InstanceContext currentInstance;
40:
41: public DefaultInstanceBuilder(TargetClassResolver classResolver) {
42: this.classResolver = classResolver;
43: }
44:
45: @Override
46: public void openObject(String property, List<String> types) {
47: Objects.requireNonNull(property);
48: final Field targetField = currentInstance.getFieldForProperty(property);
49:• assert targetField != null;
50: final Class<?> type = targetField.getType();
51: final InstanceContext<?> ctx;
52:• if (BeanClassProcessor.isIdentifierType(type)) {
53: ctx = new NodeReferenceContext<>(currentInstance, targetField, knownInstances);
54: } else {
55:• assert BeanAnnotationProcessor.isOwlClassEntity(type);
56: final Class<?> targetClass = classResolver.getTargetClass(type, types);
57: final Object instance = BeanClassProcessor.createInstance(targetClass);
58: ctx = new SingularObjectContext<>(instance,
59: BeanAnnotationProcessor.mapSerializableFields(targetClass), knownInstances);
60: currentInstance.setFieldValue(targetField, instance);
61: }
62: openInstances.push(currentInstance);
63: this.currentInstance = ctx;
64: }
65:
66: @Override
67: public <T> void openObject(Class<T> cls) {
68:• if (BeanClassProcessor.isIdentifierType(cls)) {
69: final InstanceContext<T> context = new NodeReferenceContext<>(currentInstance, knownInstances);
70:• assert currentInstance != null;
71: openInstances.push(currentInstance);
72: this.currentInstance = context;
73: } else {
74: final T instance = BeanClassProcessor.createInstance(cls);
75: final InstanceContext<T> context = new SingularObjectContext<>(instance,
76: BeanAnnotationProcessor.mapSerializableFields(cls), knownInstances);
77: replaceCurrentContext(instance, context);
78: }
79: }
80:
81: private <T> void replaceCurrentContext(T instance, InstanceContext<?> ctx) {
82:• if (currentInstance != null) {
83: currentInstance.addItem(instance);
84: openInstances.push(currentInstance);
85: }
86: this.currentInstance = ctx;
87: }
88:
89: @Override
90: public void closeObject() {
91: currentInstance.close();
92:• if (!openInstances.isEmpty()) {
93: this.currentInstance = openInstances.pop();
94: }
95: }
96:
97: @Override
98: public void openCollection(String property) {
99: Objects.requireNonNull(property);
100: final Field targetField = currentInstance.getFieldForProperty(property);
101: final InstanceContext<?> ctx;
102:• if (targetField == null) {
103:• if (currentInstance.hasPropertiesField() && !JsonLd.TYPE.equals(property)) {
104: ctx = buildPropertiesContext(property);
105: } else {
106: ctx = new DummyCollectionInstanceContext(knownInstances);
107: }
108: } else {
109: verifyPluralAttribute(property, targetField);
110: final Collection<?> instance = BeanClassProcessor.createCollection(targetField);
111:• if (JsonLd.TYPE.equals(property)) {
112: ctx = new TypesContext(instance, knownInstances,
113: BeanClassProcessor.getCollectionItemType(targetField), currentInstance.getInstanceType());
114: } else {
115: ctx = new CollectionInstanceContext<>(instance, BeanClassProcessor.getCollectionItemType(targetField),
116: knownInstances);
117: }
118: currentInstance.setFieldValue(targetField, instance);
119: }
120: openInstances.push(currentInstance);
121: this.currentInstance = ctx;
122: }
123:
124: private InstanceContext<?> buildPropertiesContext(String property) {
125: final Field propsField = BeanAnnotationProcessor.getPropertiesField(currentInstance.getInstanceType());
126: BeanClassProcessor.verifyPropertiesFieldType(propsField);
127: Map<?, ?> propertiesMap =
128: (Map<?, ?>) BeanClassProcessor.getFieldValue(propsField, currentInstance.getInstance());
129:• if (propertiesMap == null) {
130: propertiesMap = new HashMap<>();
131: currentInstance.setFieldValue(propsField, propertiesMap);
132: }
133: return new PropertiesInstanceContext(propertiesMap, property, propsField);
134: }
135:
136: private void verifyPluralAttribute(String property, Field field) {
137:• if (!isPlural(property)) {
138: throw JsonLdDeserializationException.singularAttributeCardinalityViolated(property, field);
139: }
140: }
141:
142: @Override
143: public void openCollection(CollectionType collectionType) {
144: final Collection<?> collection = BeanClassProcessor.createCollection(collectionType);
145: final InstanceContext<?> context = new CollectionInstanceContext<>(collection, knownInstances);
146: replaceCurrentContext(collection, context);
147: }
148:
149: @Override
150: public void closeCollection() {
151:• if (!openInstances.isEmpty()) {
152: currentInstance = openInstances.pop();
153: }
154: }
155:
156: @Override
157: public void addValue(String property, Object value) {
158:• assert currentInstance != null;
159:• if (JsonLd.ID.equals(property)) {
160: currentInstance.setIdentifierValue(value);
161: return;
162: }
163: final Field targetField = currentInstance.getFieldForProperty(property);
164:• assert targetField != null;
165: // This is in case there is only one value in the JSON-LD array, because then it might be treated as single valued attribute
166:• if (BeanClassProcessor.isCollection(targetField)) {
167: openCollection(property);
168: addValue(value);
169: closeCollection();
170: } else {
171: currentInstance.setFieldValue(targetField, value);
172: }
173: }
174:
175: @Override
176: public void addValue(Object value) {
177:• assert currentInstance != null;
178: currentInstance.addItem(value);
179: }
180:
181: @Override
182: public void addNodeReference(String property, String nodeId) {
183: final Field field = currentInstance.getFieldForProperty(property);
184:• assert field != null;
185: final Class<?> type = field.getType();
186:• if (BeanClassProcessor.isIdentifierType(type)) {
187: currentInstance.setFieldValue(field, nodeId);
188: } else {
189: currentInstance.setFieldValue(field, getKnownInstance(nodeId));
190: }
191: }
192:
193: private Object getKnownInstance(String nodeId) {
194:• if (!knownInstances.containsKey(nodeId)) {
195: throw new JsonLdDeserializationException(
196: "Node with IRI " + nodeId + " cannot be referenced, because it has not been encountered yet.");
197: }
198: return knownInstances.get(nodeId);
199: }
200:
201: @Override
202: public void addNodeReference(String nodeId) {
203: final Class<?> targetType = getCurrentCollectionElementType();
204:• if (BeanClassProcessor.isIdentifierType(targetType)) {
205: currentInstance.addItem(nodeId);
206: } else {
207: currentInstance.addItem(getKnownInstance(nodeId));
208: }
209: }
210:
211: @Override
212: public Object getCurrentRoot() {
213:• return currentInstance != null ? currentInstance.getInstance() : null;
214: }
215:
216: @Override
217: public Class<?> getCurrentCollectionElementType() {
218: try {
219: return currentInstance.getItemType();
220: } catch (UnsupportedOperationException e) {
221: throw new JsonLdDeserializationException("The current instance is not a collection.", e);
222: }
223: }
224:
225: @Override
226: public boolean isPlural(String property) {
227:• assert isPropertyMapped(property);
228: final Field mappedField = currentInstance.getFieldForProperty(property);
229:• return mappedField == null || BeanClassProcessor.isCollection(mappedField);
230: }
231:
232: @Override
233: public boolean isPropertyMapped(String property) {
234:• return currentInstance.isPropertyMapped(property) || JsonLd.TYPE.equals(property);
235: }
236:
237: @Override
238: public Class<?> getCurrentContextType() {
239: return currentInstance.getInstanceType();
240: }
241: }