Package: InstanceContext
InstanceContext
name | instruction | branch | complexity | line | method | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
InstanceContext(Object, Map) |
|
|
|
|
|
||||||||||||||||||||
addItem(Object) |
|
|
|
|
|
||||||||||||||||||||
close() |
|
|
|
|
|
||||||||||||||||||||
getFieldForProperty(String) |
|
|
|
|
|
||||||||||||||||||||
getIdentifier() |
|
|
|
|
|
||||||||||||||||||||
getInstance() |
|
|
|
|
|
||||||||||||||||||||
getInstanceType() |
|
|
|
|
|
||||||||||||||||||||
getItemType() |
|
|
|
|
|
||||||||||||||||||||
hasPropertiesField() |
|
|
|
|
|
||||||||||||||||||||
isBlankNodeIdentifier(String) |
|
|
|
|
|
||||||||||||||||||||
isPropertyMapped(String) |
|
|
|
|
|
||||||||||||||||||||
resolveAssignableValue(Class, Object) |
|
|
|
|
|
||||||||||||||||||||
setFieldValue(Field, Object) |
|
|
|
|
|
||||||||||||||||||||
setIdentifierValue(String) |
|
|
|
|
|
||||||||||||||||||||
supports(String) |
|
|
|
|
|
Coverage
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.deserialization;
14:
15: import cz.cvut.kbss.jsonld.JsonLd;
16: import cz.cvut.kbss.jsonld.common.BeanAnnotationProcessor;
17: import cz.cvut.kbss.jsonld.deserialization.util.DataTypeTransformer;
18: import cz.cvut.kbss.jsonld.exception.UnknownPropertyException;
19:
20: import java.lang.reflect.Field;
21: import java.util.Map;
22: import java.util.Optional;
23:
24: abstract class InstanceContext<T> {
25:
26: /**
27: * Blank node id start, as per <a href="https://www.w3.org/TR/turtle/#BNodes">https://www.w3.org/TR/turtle/#BNodes</a>
28: */
29: private static final String BLANK_NODE_ID_START = "_:";
30:
31: T instance;
32:
33: private String identifier;
34:
35: final Map<String, Object> knownInstances;
36:
37: InstanceContext(T instance, Map<String, Object> knownInstances) {
38: this.instance = instance;
39: this.knownInstances = knownInstances;
40: }
41:
42: T getInstance() {
43: return instance;
44: }
45:
46: @SuppressWarnings("unchecked")
47: Class<T> getInstanceType() {
48: return (Class<T>) instance.getClass();
49: }
50:
51: /**
52: * Sets identifier of the instance specified by this context.
53: *
54: * @param value Identifier value
55: */
56: void setIdentifierValue(String value) {
57: final Field idField = getFieldForProperty(JsonLd.ID);
58: final boolean blankNode = isBlankNodeIdentifier(value);
59:• if (idField == null) {
60:• if (blankNode) {
61: return;
62: } else {
63: throw UnknownPropertyException.create(JsonLd.ID, getInstanceType());
64: }
65: }
66:• if (blankNode && !idField.getType().equals(String.class)) {
67: return;
68: }
69: setFieldValue(idField, value);
70: this.identifier = value;
71: knownInstances.put(value, instance);
72: }
73:
74: private static boolean isBlankNodeIdentifier(String identifier) {
75: return identifier.startsWith(BLANK_NODE_ID_START);
76: }
77:
78: /**
79: * Gets the instance identifier.
80: * <p>
81: * Note that the identifier may not be available.
82: *
83: * @return Identifier value, or {@code null} if it is not available (it has not been set or is not applicable in
84: * this context)
85: * @see #setIdentifierValue(String)
86: */
87: String getIdentifier() {
88: return identifier;
89: }
90:
91: // These methods are intended for overriding, because the behaviour is supported only by some context implementations
92:
93: /**
94: * Gets a Java field mapped by the specified property.
95: * <p>
96: * This applies to singular object contexts only.
97: *
98: * @param property Property IRI
99: * @return Field mapped by the specified property. Can be {@code null}
100: */
101: Field getFieldForProperty(String property) {
102: throw new UnsupportedOperationException("Not supported by this type of instance context.");
103: }
104:
105: /**
106: * Sets value of the specified field on the instance represented by this context
107: *
108: * @param field The field to set
109: * @param value The value to set
110: */
111: void setFieldValue(Field field, Object value) {
112: // Do nothing
113: }
114:
115: /**
116: * Adds item to the collection represented by this context.
117: *
118: * @param item Item to add
119: */
120: void addItem(Object item) {
121: // Do nothing
122: }
123:
124: /**
125: * Gets type of the element type of a collection represented by this context.
126: *
127: * @return Collection element type
128: */
129: Class<?> getItemType() {
130: throw new UnsupportedOperationException("Not supported by this type of instance context.");
131: }
132:
133: Optional<Object> resolveAssignableValue(Class<?> targetType, Object value) {
134:• if (!targetType.isAssignableFrom(value.getClass())) {
135:• if (knownInstances.containsKey(value.toString())) {
136: final Object known = knownInstances.get(value.toString());
137:• if (!targetType.isAssignableFrom(known.getClass())) {
138: return Optional.ofNullable(DataTypeTransformer.transformValue(value, targetType));
139: } else {
140: return Optional.of(known);
141: }
142: } else {
143: return Optional.ofNullable(DataTypeTransformer.transformValue(value, targetType));
144: }
145: }
146: return Optional.of(value);
147: }
148:
149: /**
150: * Whether the specified property is mapped by a field in this context.
151: * <p>
152: * Note that if the context represents an instance with a {@link cz.cvut.kbss.jopa.model.annotations.Properties}
153: * field, every property is considered mapped
154: *
155: * @param property The property to check
156: * @return {@code true} if a field mapping the property exists in this context, {@code false} otherwise
157: */
158: boolean isPropertyMapped(String property) {
159: // Default behavior
160: return false;
161: }
162:
163: /**
164: * Checks whether the specified property is supported by this context.
165: * <p>
166: * A property is supported by a context for deserialization if it is mapped and the mapped field does not have
167: * read-only access.
168: *
169: * @param property The property to check
170: * @return Whether property is supported by this context
171: * @see #isPropertyMapped(String)
172: * @see cz.cvut.kbss.jsonld.annotation.JsonLdProperty.Access#READ_ONLY
173: */
174: boolean supports(String property) {
175: // Default behavior
176: return false;
177: }
178:
179: /**
180: * Checks whether the class represented by this context contains a {@link cz.cvut.kbss.jopa.model.annotations.Properties}
181: * field.
182: *
183: * @return Whether the represented class has properties field
184: */
185: boolean hasPropertiesField() {
186: return BeanAnnotationProcessor.hasPropertiesField(getInstanceType());
187: }
188:
189: /**
190: * Called when this context is being closed
191: */
192: void close() {
193: // Do nothing by default
194: }
195: }